Largest subsequence such that its prefix sum never gets negative
Last Updated :
24 Feb, 2023
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++
#include <bits/stdc++.h>
using namespace std;
void FindMaxSubsequence( int * a, int n)
{
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++) {
s += a[i];
v1.push_back(a[i]);
c++;
if (a[i] < 0)
v.push(a[i]);
if (s < 0) {
s -= v.top();
it = find(v1.begin(), v1.end(), v.top());
v1.erase(it);
v.pop();
c--;
}
}
for ( auto i : v1) {
cout << i << " " ;
}
}
int main()
{
int arr[] = { -3, -3, -7, -7, -1, -7,
3, 3, -2, -1, 0, -7 };
int N = sizeof (arr) / sizeof (arr[0]);
FindMaxSubsequence(arr, N);
return 0;
}
|
Python3
from queue import PriorityQueue
def FindMaxSubsequence(a, n):
v = PriorityQueue()
c = 0
s = 0
v1 = []
for i in range (n):
s + = a[i]
v1.append(a[i])
c = c + 1
if a[i] < 0 :
v.put(a[i])
if (s < 0 ):
t = v.get()
s = s - t
v1.remove(t)
c = c - 1
for i in range ( len (v1)):
print (v1[i], end = " " )
arr = [ - 3 , - 3 , - 7 , - 7 , - 1 , - 7 ,
3 , 3 , - 2 , - 1 , 0 , - 7 ]
N = len (arr)
FindMaxSubsequence(arr, N)
|
Java
import java.util.*;
class GFG {
static void findMaxSubsequence( int [] a, int n) {
PriorityQueue<Integer> v = new PriorityQueue<>();
int c = 0 , s = 0 ;
List<Integer> v1 = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
s += a[i];
v1.add(a[i]);
c++;
if (a[i] < 0 ) {
v.add(a[i]);
}
if (s < 0 ) {
s -= v.peek();
v1.remove(v.poll());
c--;
}
}
for ( int i : v1) {
System.out.print(i + " " );
}
}
public static void main(String[] args) {
int [] arr = { - 3 , - 3 , - 7 , - 7 , - 1 , - 7 , 3 , 3 , - 2 , - 1 , 0 , - 7 };
int N = arr.length;
findMaxSubsequence(arr, N);
}
}
|
Javascript
function FindMaxSubsequence(a, n) {
let v = [];
let c = 0;
let s = 0;
let v1 = [];
for (let i = 0; i < n; i++) {
s += a[i];
v1.push(a[i]);
c = c + 1;
if (a[i] < 0) {
v.push(a[i]);
}
if (s < 0) {
v.sort((a, b) => a - b);
let t = v.shift();
s = s - t;
let index = v1.indexOf(t);
v1.splice(index, 1);
c = c - 1;
}
}
console.log(v1.join( " " ));
}
let arr = [-3, -3, -7, -7, -1, -7, 3, 3, -2, -1, 0, -7];
let N = arr.length;
FindMaxSubsequence(arr, N);
|
C#
using System;
using System.Collections.Generic;
class GFG {
static void FindMaxSubsequence( int [] a, int n) {
var v = new PriorityQueue< int >();
int c = 0, s = 0;
List< int > v1 = new List< int >();
for ( int i = 0; i < n; i++) {
s += a[i];
v1.Add(a[i]);
c++;
if (a[i] < 0) {
v.Enqueue(a[i]);
}
if (s < 0) {
s -= v.Peek();
v1.Remove(v.Dequeue());
c--;
}
}
foreach ( int i in v1) {
Console.Write(i + " " );
}
}
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() {
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;
}
}
public static void Main( string [] args) {
int [] arr = { -3, -3, -7, -7, -1, -7, 3, 3, -2, -1, 0, -7 };
int N = arr.Length;
FindMaxSubsequence(arr, N);
}
}
|
Time Complexity: O(N logN)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...