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++ 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;
} |
# 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 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);
}
} |
// 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 |
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);
}
} |
3 3 -2 -1 0
Time Complexity: O(N logN)
Auxiliary Space: O(N)