Given an array of N integers. Each i’th element increases your sum by a[i], where a[i] can be negative which may decrease your sum. You start with sum=0 and iterate the array from left to right. at each index, you may add the element to your sum or not Your task is to add the maximum number of elements in your sum, given that the sum remains non-negative.
Examples:
Input: arr = {4, -4, 1, -3, 1, -3}
Output: 5
Explanation: Take integers 4,1,-3,1,-3Input: arr = {-3, -3, -7, -7, -1, -7, 3, 3, -2, -1, 0, -7}
Output: 5
Approach: To solve the problem follow the below idea:
The idea is to iterate through an array, adding each element to a sum and keeping track of the count, while adjusting the sum to remain non-negative by removing the most negative elements when needed. The result is the maximum number of elements that can be added to the sum without making it negative.
Step-by-step approach:
- Start with variables for the current sum (currentSum) and the count of elements added (elementsAdded), both initially set to 0.
- Use a priority queue (negativeElements) to store negative values.
-
Loop through each element of the array.
- Add the current element to currentSum and increment elementsAdded.
- Push the negative of the current element to the priority queue.
- Check if currentSum is negative.
-
If negative, enter a loop:
- Reduce elementsAdded.
- Remove the most negative element from the priority queue and adjust currentSum.
- Repeat until currentSum becomes non-negative.
- After processing all elements, the result is the maximum number of elements that can be added to the sum while keeping it non-negative.
Below is the implementation of the above approach:
#include <bits/stdc++.h> using namespace std;
int solve(vector< int >& arr)
{ // Update the current sum and count of elements added to
// the sum
long long currentSum = 0;
int elementsAdded = 0;
// Priority queue to store negative of elements for
// efficient removal
priority_queue< int > negativeElements;
for ( int i = 0; i < arr.size(); i++) {
// Input the current element
int currentElement = arr[i];
// Add the current element to the sum and
// increment the count
currentSum += currentElement;
elementsAdded++;
negativeElements.push(-currentElement);
// Check if the current sum is negative
while (currentSum < 0) {
// If so, reduce the count of elements added
// and adjust the sum
elementsAdded--;
currentSum += negativeElements.top();
negativeElements.pop();
}
}
// Output the maximum number of elements that can be
// added to the sum
return elementsAdded;
} // Driver code int main()
{ vector< int > arr = { 4, -4, 1, -3, 1, -3 };
int result = solve(arr);
cout << result << endl;
return 0;
} |
import java.util.PriorityQueue;
import java.util.Vector;
public class MaxElementsInSum {
// Function to solve the problem and calculate the
// maximum number of elements that can be added to the
// sum
static int solve(Vector<Integer> arr)
{
// Update the current sum and count of elements
// added to the sum
long currentSum = 0 ;
int elementsAdded = 0 ;
// Priority queue to store elements for efficient
// removal
PriorityQueue<Integer> elements
= new PriorityQueue<>();
for ( int i = 0 ; i < arr.size(); i++) {
// Input the current element
int currentElement = arr.get(i);
// Add the current element to the sum and
// increment the count
currentSum += currentElement;
elementsAdded++;
elements.add(currentElement);
// Check if the current sum is negative
if (currentSum < 0 ) {
// If so, reduce the count of elements added
// and adjust the sum by removing the
// smallest element
elementsAdded--;
currentSum -= elements.poll();
}
}
// Output the maximum number of elements that can be
// added to the sum
return elementsAdded;
}
// Driver code
public static void main(String[] args)
{
Vector<Integer> arr = new Vector<>();
arr.add( 4 );
arr.add(- 4 );
arr.add( 1 );
arr.add(- 3 );
arr.add( 1 );
arr.add(- 3 );
int result = solve(arr);
System.out.println(result);
}
} |
import heapq
def solve(arr):
# Update the current sum and count of elements added to the sum
current_sum = 0
elements_added = 0
# List to store elements for efficient removal
elements = []
for current_element in arr:
# Add the current element to the sum and increment the count
current_sum + = current_element
elements_added + = 1
heapq.heappush(elements, current_element)
# Check if the current sum is negative
while current_sum < 0 :
# If so, reduce the count of elements added
# and adjust the sum by removing the smallest element
elements_added - = 1
current_sum - = heapq.heappop(elements)
# Output the maximum number of elements that can be added to the sum
return elements_added
# Driver code arr = [ 4 , - 4 , 1 , - 3 , 1 , - 3 ]
result = solve(arr)
print (result)
|
using System;
using System.Collections.Generic;
class Program
{ static int Solve(List< int > arr)
{
// Update the current sum and count of elements added to the sum
long currentSum = 0;
int elementsAdded = 0;
// Priority queue to store negative of elements for efficient removal
PriorityQueue< int > negativeElements = new PriorityQueue< int >();
for ( int i = 0; i < arr.Count; i++)
{
// Input the current element
int currentElement = arr[i];
// Add the current element to the sum and increment the count
currentSum += currentElement;
elementsAdded++;
negativeElements.Push(-currentElement);
// Check if the current sum is negative
while (currentSum < 0)
{
// If so, reduce the count of elements added and adjust the sum
elementsAdded--;
currentSum += negativeElements.Pop();
}
}
// Output the maximum number of elements that can be added to the sum
return elementsAdded;
}
// Driver code
static void Main()
{
List< int > arr = new List< int > { 4, -4, 1, -3, 1, -3 };
int result = Solve(arr);
Console.WriteLine(result);
}
} // PriorityQueue class to simulate priority queue behavior class PriorityQueue<T> where T : IComparable<T>
{ private List<T> heap;
public PriorityQueue()
{
heap = new List<T>();
}
public int Count
{
get { return heap.Count; }
}
public void Push(T value)
{
heap.Add(value);
int currentIndex = heap.Count - 1;
while (currentIndex > 0)
{
int parentIndex = (currentIndex - 1) / 2;
if (heap[currentIndex].CompareTo(heap[parentIndex]) > 0)
{
Swap(currentIndex, parentIndex);
currentIndex = parentIndex;
}
else
{
break ;
}
}
}
public T Pop()
{
if (heap.Count == 0)
{
throw new InvalidOperationException( "Priority queue is empty" );
}
T root = heap[0];
heap[0] = heap[heap.Count - 1];
heap.RemoveAt(heap.Count - 1);
int currentIndex = 0;
while ( true )
{
int leftChildIndex = 2 * currentIndex + 1;
int rightChildIndex = 2 * currentIndex + 2;
if (leftChildIndex >= heap.Count)
{
break ;
}
int childIndex = leftChildIndex;
if (rightChildIndex < heap.Count &&
heap[rightChildIndex].CompareTo(heap[leftChildIndex]) > 0)
{
childIndex = rightChildIndex;
}
if (heap[currentIndex].CompareTo(heap[childIndex]) < 0)
{
Swap(currentIndex, childIndex);
currentIndex = childIndex;
}
else
{
break ;
}
}
return root;
}
private void Swap( int index1, int index2)
{
T temp = heap[index1];
heap[index1] = heap[index2];
heap[index2] = temp;
}
} |
// Javascript code for the above approach: function solve(arr) {
// Update the current sum and count of elements added to the sum
let currentSum = 0;
let elementsAdded = 0;
// Priority queue to store negative of elements for efficient removal
const negativeElements = new PriorityQueue(); // Using a Max Priority Queue
for (let i = 0; i < arr.length; i++) {
// Input the current element
const currentElement = arr[i];
// Add the current element to the sum and increment the count
currentSum += currentElement;
elementsAdded++;
negativeElements.enqueue(-currentElement);
// Check if the current sum is negative
while (currentSum < 0) {
// If so, reduce the count of elements added and adjust the sum
elementsAdded--;
currentSum += negativeElements.dequeue().element;
}
}
// Output the maximum number of elements that can be added to the sum
return elementsAdded;
} // A simple PriorityQueue implementation class PriorityQueue { // creates a PriorityQueue queue
// internally uses arrays to store the data
constructor(compare) {
this .queue = [];
this .compare = compare;
}
// adding to queue
enqueue(item) {
this .queue.push(item);
// sort to maintain PriorityQueue order
this .queue.sort( this .compare);
}
// dequeue operation using shift function
dequeue() {
if ( this .isEmpty()) {
return null ;
}
return this .queue.shift();
}
// isEmpty utility funtion
// to check whether the queue is empty
isEmpty() {
return this .queue.length === 0;
}
} // Driver code const arr = [4, -4, 1, -3, 1, -3]; const result = solve(arr); console.log(result); // This code is contributed by ragul21 |
5
Time Complexity: O(nlog(n))
Auxiliary Space: O(n)