Check if the product of the K largest sums of subarrays is greater than M

Given an array arr[] of N integers and two integers M and K. The task is to check if the product of the K largest sum of contiguous subarrays is greater than M.

Examples:

Input: arr[] = {10, -4, -2, 7}, M = 659, K = 3
Output: Yes
The 3 largest contiguous sums for the subarrays
are of the subarrays {10, -4, -2, 7}, {10} and {7}
i.e. 11, 10 and 7, the product is 11 * 10 * 7 = 770
which is greater than 659.

Input: arr[] = {4, -3, 8}, M = 100, K = 6
Output: No

A brute force approach is to store all the sum of the contiguous subarray in some other array and sort it then calculate the product of the K largest sum and check if the value is greater than M. But in case of the size of the array being too large, the number of continuous subarrays will increase and hence the auxiliary array will take more space.



A better approach is to store the prefix sum of the array in the array itself. Then the sum of the subarray arr[i…j] can be calculated as arr[j] – arr[i – 1]. Now for storing the K largest sum contiguous subarrays, use a min-heap (priority queue) in which only the K maximum sums will be stored at a time. After that for every other element, check if the element is greater than the top element of the min-heap if yes then that element will be inserted to the min-heap and the top element will be popped from the min-heap. In the end, calculate the product of all the elements in the min-heap and check if it is greater than M or not.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function that returns true is the product
// of the maximum K subarrays sums of
// arr[] is greater than M
bool checkKSum(int arr[], int n, int k, int M)
{
    // Update the array to store the prefix sum
    for (int i = 1; i < n; i++)
        arr[i] = arr[i - 1] + arr[i];
  
    // Min-heap
    priority_queue<int, vector<int>, greater<int> > Q;
  
    // Starting index of the subarray
    for (int i = 0; i < n; i++) {
  
        // Ending index of the subarray
        for (int j = i; j < n; j++) {
  
            // To store the sum of the
            // subarray arr[i...j]
            int sum = (i == 0) ? arr[j] : arr[j] - arr[i - 1];
  
            // If the queue has less then k elements
            // then simply push it
            if (Q.size() < k)
                Q.push(sum);
  
            else {
  
                // If the min heap has equal exactly k
                // elements then check if the current
                // sum is greater than the smallest
                // of the current k sums stored
                if (Q.top() < sum) {
                    Q.pop();
                    Q.push(sum);
                }
            }
        }
    }
  
    // Calculate the product of
    // the k largest sum
    long product = 1;
    while (!Q.empty()) {
        product *= Q.top();
        Q.pop();
    }
  
    // If the product is greater than M
    if (product > M)
        return true;
  
    return false;
}
  
// Driver code
int main()
{
    int a[] = { 10, -4, -2, 7 };
    int n = sizeof(a) / sizeof(a[0]);
    int k = 3, M = 659;
  
    if (checkKSum(a, n, k, M))
        cout << "Yes";
    else
        cout << "No";
  
    return 0;
}
chevron_right

Output:
Yes

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :
Practice Tags :