Open In App

Maximum number of elements that can be taken

Last Updated : 23 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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,-3

Input: 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:

C++




#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;
}


Java




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);
    }
}


Python3




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)


C#




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




// 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


Output

5









Time Complexity: O(nlog(n))
Auxiliary Space: O(n)



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

Similar Reads