Open In App

Largest subsequence such that its prefix sum never gets negative

Last Updated : 24 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] containing integers. The task is to find the largest subsequence such that at any point in time prefix sum of that subsequence is not negative.

Examples:

Input: arr[] = {-3, -3, -7, -7, -1, -7, 3, 3, -2, -1, 0, -7}
Output: 3 3 -2 -1 0
Explanation: Adding -3 makes sum negative so it can’t be included, Similarly -3, -7, -7, -1, -7, -7 can’t be included. Only 3, 3, -2, -1, 0 can be included.

Input: arr[] = {3, 4, -8, 6, -7, 5}
Output: 3 4 6 -7 5
Explanation: 3, 4 can be added as they make sum positive but when -8 is added the sum becomes negative so it can’t be included rest all numbers can be included.

 

Approach: This problem can be solved by using Min Heap. Follow the steps below to solve the given problem. 

  • At first Initialize variables ‘s’=0 and ‘c’=0, to store the sum of array elements and count of elements respectively.
  • Take a min priority queue, to store the negative elements.
  • Now start from the leftmost element take the sum of the current element, push it to vector, and increase the count.
  • If the current element is less than zero push it in the min priority queue.
  • If the sum becomes less than zero then subtract the largest negative number(or smallest number ) of priority queue from sum and pop that element from the priority queue and also decrease the count of the element, as well as delete that element from the vector.
  • After traversing the whole array we get the desired subsequence in vector.

Below is the implementation of the above approach.

C++




// C++ program for above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the largest subsequence
// satisfying given conditions
void FindMaxSubsequence(int* a, int n)
{
    // Min priority queue
    priority_queue<int, vector<int>,
                   greater<int> >
        v;
 
    int c = 0, s = 0;
 
    vector<int> v1;
    vector<int>::iterator it;
 
    for (int i = 0; i < n; i++) {
        // Current sum
        s += a[i];
 
        // Push the subsequence
        v1.push_back(a[i]);
 
        // Current count
        c++;
 
        // Storing negative elements
        // in priority queue
        if (a[i] < 0)
            v.push(a[i]);
 
        // If sum is less than zero
        // than subtract largest
        // negative number from left
        // and decrease the count
        if (s < 0) {
            s -= v.top();
            it = find(v1.begin(), v1.end(), v.top());
 
            // Erase the added vector
            v1.erase(it);
            v.pop();
            c--;
        }
    }
 
    // Largest subsequence
    for (auto i : v1) {
        cout << i << " ";
    }
}
 
// Driver Code
int main()
{
 
    int arr[] = { -3, -3, -7, -7, -1, -7,
                  3, 3, -2, -1, 0, -7 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    FindMaxSubsequence(arr, N);
    return 0;
}


Python3




# Python code for the above approach
from queue import PriorityQueue
 
# Function to find the largest subsequence
# satisfying given conditions
def FindMaxSubsequence(a, n):
 
    # Min priority queue
    v = PriorityQueue()
 
    c = 0
    s = 0
    v1 = []
 
    for i in range(n):
        # Current sum
        s += a[i]
 
        # Push the subsequence
        v1.append(a[i])
 
        # Current count
        c = c + 1
 
        # Storing negative elements
        # in priority queue
        if a[i] < 0:
            v.put(a[i])
 
        # If sum is less than zero
        # than subtract largest
        # negative number from left
        # and decrease the count
        if (s < 0):
            t = v.get()
            s = s-t
            # Erase the added vector
            v1.remove(t)
 
            c = c - 1
 
    # Largest subsequence
    for i in range(len(v1)):
        print(v1[i], end = " ")
 
# Driver Code
arr = [-3, -3, -7, -7, -1, -7,
       3, 3, -2, -1, 0, -7]
 
N = len(arr)
 
# Function Call
FindMaxSubsequence(arr, N)
 
# This code is contributed by Potta Lokesh


Java




// Java program for above approach
 
import java.util.*;
 
class GFG {
    // Function to find the largest subsequence
    // satisfying given conditions
    static void findMaxSubsequence(int[] a, int n) {
        // Min priority queue
        PriorityQueue<Integer> v = new PriorityQueue<>();
 
        int c = 0, s = 0;
 
        List<Integer> v1 = new ArrayList<>();
 
        for (int i = 0; i < n; i++) {
            // Current sum
            s += a[i];
 
            // Push the subsequence
            v1.add(a[i]);
 
            // Current count
            c++;
 
            // Storing negative elements
            // in priority queue
            if (a[i] < 0) {
                v.add(a[i]);
            }
 
            // If sum is less than zero
            // than subtract largest
            // negative number from left
            // and decrease the count
            if (s < 0) {
                s -= v.peek();
                v1.remove(v.poll());
                c--;
            }
        }
 
        // Largest subsequence
        for (int i : v1) {
            System.out.print(i + " ");
        }
    }
 
    // Driver code
    public static void main(String[] args) {
         
        int[] arr = { -3, -3, -7, -7, -1, -7, 3, 3, -2, -1, 0, -7 };
        int N = arr.length;
 
        // Function Call
        findMaxSubsequence(arr, N);
    }
}


Javascript




// Function to find the largest subsequence
// satisfying given conditions
function FindMaxSubsequence(a, n) {
  // Min priority queue
  let v = [];
 
  let c = 0;
  let s = 0;
  let v1 = [];
 
  for (let i = 0; i < n; i++) {
    // Current sum
    s += a[i];
 
    // Push the subsequence
    v1.push(a[i]);
 
    // Current count
    c = c + 1;
 
    // Storing negative elements
    // in priority queue
    if (a[i] < 0) {
      v.push(a[i]);
    }
 
    // If sum is less than zero
    // than subtract largest
    // negative number from left
    // and decrease the count
    if (s < 0) {
      v.sort((a, b) => a - b);
      let t = v.shift();
      s = s - t;
      // Erase the added vector
      let index = v1.indexOf(t);
      v1.splice(index, 1);
 
      c = c - 1;
    }
  }
 
  // Largest subsequence
  console.log(v1.join(" "));
}
 
// Driver Code
let arr = [-3, -3, -7, -7, -1, -7, 3, 3, -2, -1, 0, -7];
 
let N = arr.length;
 
// Function Call
FindMaxSubsequence(arr, N);
 
// this code is contributed by edula vinay kumar reddy


C#




using System;
using System.Collections.Generic;
 
class GFG {
    // Function to find the largest subsequence
    // satisfying given conditions
    static void FindMaxSubsequence(int[] a, int n) {
        // Min priority queue
        var v = new PriorityQueue<int>();
 
        int c = 0, s = 0;
 
        List<int> v1 = new List<int>();
 
        for (int i = 0; i < n; i++) {
            // Current sum
            s += a[i];
 
            // Push the subsequence
            v1.Add(a[i]);
 
            // Current count
            c++;
 
            // Storing negative elements
            // in priority queue
            if (a[i] < 0) {
                v.Enqueue(a[i]);
            }
 
            // If sum is less than zero
            // than subtract largest
            // negative number from left
            // and decrease the count
            if (s < 0) {
                s -= v.Peek();
                v1.Remove(v.Dequeue());
                c--;
            }
        }
 
        // Largest subsequence
        foreach (int i in v1) {
            Console.Write(i + " ");
        }
    }
 
    // as C# don't have inbuilt priorityQueue so implemented it here using class
    // Priority queue implementation
    class PriorityQueue<T> where T : IComparable<T> {
        private List<T> data;
 
        public PriorityQueue() {
            this.data = new List<T>();
        }
 
        public void Enqueue(T item) {
            data.Add(item);
            int ci = data.Count - 1;
            while (ci > 0) {
                int pi = (ci - 1) / 2;
                if (data[ci].CompareTo(data[pi]) >= 0)
                    break;
                T tmp = data[ci]; data[ci] = data[pi]; data[pi] = tmp;
                ci = pi;
            }
        }
 
        public T Dequeue() {
            // Assumes pq is not empty; up to calling code
            int li = data.Count - 1;
            T frontItem = data[0];
            data[0] = data[li];
            data.RemoveAt(li);
 
            --li;
            int pi = 0;
            while (true) {
                int ci = pi * 2 + 1;
                if (ci > li) break;
                int rc = ci + 1;
                if (rc <= li && data[rc].CompareTo(data[ci]) < 0)
                    ci = rc;
                if (data[pi].CompareTo(data[ci]) <= 0) break;
                T tmp = data[pi]; data[pi] = data[ci]; data[ci] = tmp;
                pi = ci;
            }
            return frontItem;
        }
 
        public T Peek() {
            T frontItem = data[0];
            return frontItem;
        }
 
        public int Count() {
            return data.Count;
        }
    }
 
    // Driver code
    public static void Main(string[] args) {
        int[] arr = { -3, -3, -7, -7, -1, -7, 3, 3, -2, -1, 0, -7 };
        int N = arr.Length;
 
        // Function Call
        FindMaxSubsequence(arr, N);
    }
}


 
 

Output

3 3 -2 -1 0 

 

Time Complexity: O(N logN) 
Auxiliary Space: O(N)

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads