# K maximum sums of overlapping contiguous sub-arrays

Given an array of Integers and an Integer value k, find out k sub-arrays(may be overlapping), which have k maximum sums.

Examples:

```Input : arr = {4, -8, 9, -4, 1, -8, -1, 6}, k = 4
Output : 9 6 6 5 Input : arr = {-2, -3, 4, -1, -2, 1, 5, -3}, k= 3
Output : 7 6 5
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Using Kadane’s Algorithm we can find the maximum contiguous subarray sum of an array. But in the case Kadane’s Algorithm does not work. As whenever we hit an negative number in the array we set the max_ending_here variable to zero, hence we miss the possibilities for second and so on maximums.

Here we is an algorithm presented by Sung Eun Bae and Tadao Takaoka which computes the maximum sub-array sum problem in O(n) time and k maximum sub-array sum problem in O(k*n) time.

First we look at the problem of only maximum sub-array sum using this method:

Prerequisite:
1. Prefix sum array
2. Maximum subarray sum in O(n) using prefix sum

Method for k-maximum sub-arrays:

```1. Calculate the prefix sum of the input array.
2. Take cand, maxi and mini as arrays of size k.
3. Initialize mini = 0 for the same reason as previous.
4. for each value of the prefix_sum[i] do
(i). update cand[j] value by prefix_sum[i] - mini[j]
(ii). maxi will be the maximum k elements of maxi and cand
(iii). if prefix_sum is less than all values of mini, then
include it in mini and remove the maximum element from mini
// After the ith iteration mini holds k minimum prefix sum upto
// index i and maxi holds k maximum overlapping sub-array sums
// upto index i.
5. return maxi
```

Throughout this calculation method, we keep maxi in non-increasing and mini in non-decreasing order.

## C++

 `// C++ program to find out k maximum sum of ` `// overlapping sub-arrays ` `#include ` `#include ` `#include ` ` `  `using` `namespace` `std; ` ` `  `// Function to compute prefix-sum of the input array ` `vector<``int``> prefix_sum(vector<``int``> arr, ``int` `n) ` `{ ` `    ``vector<``int``> pre_sum; ` `    ``pre_sum.push_back(arr); ` `    ``for` `(``int` `i = 1; i < n; i++)  ` `        ``pre_sum.push_back(pre_sum[i - 1] + arr[i]);     ` `    ``return` `pre_sum; ` `} ` ` `  `// Update maxi by k maximum values from maxi and cand ` `void` `maxMerge(vector<``int``>& maxi, vector<``int``> cand) ` `{ ` `    ``// Here cand and maxi arrays are in non-increasing ` `    ``// order beforehand. Now, j is the index of the ` `    ``// next cand element and i is the index of next ` `    ``// maxi element. Traverse through maxi array. ` `    ``// If cand[j] > maxi[i] insert cand[j] at the ith ` `    ``// position in the maxi array and remove the minimum ` `    ``// element of the maxi array i.e. the last element ` `    ``// and increase j by 1 i.e. take the next element ` `    ``// from cand. ` `    ``int` `k = maxi.size(); ` `    ``int` `j = 0; ` `    ``for` `(``int` `i = 0; i < k; i++) { ` `        ``if` `(cand[j] > maxi[i]) { ` `            ``maxi.insert(maxi.begin() + i, cand[j]); ` `            ``maxi.erase(maxi.begin() + k); ` `            ``j += 1; ` `        ``} ` `    ``} ` `} ` ` `  `// Insert prefix_sum[i] to mini array if needed ` `void` `insertMini(vector<``int``>& mini, ``int` `pre_sum) ` `{ ` `    ``// Traverse the mini array from left to right. ` `    ``// If prefix_sum[i] is less than any element ` `    ``// then insert prefix_sum[i] at that position ` `    ``// and delete maximum element of the mini array ` `    ``// i.e. the rightmost element from the array. ` `    ``int` `k = mini.size(); ` `    ``for` `(``int` `i = 0; i < k; i++) { ` `        ``if` `(pre_sum < mini[i]) { ` `            ``mini.insert(mini.begin() + i, pre_sum); ` `            ``mini.erase(mini.begin() + k); ` `            ``break``; ` `        ``} ` `    ``} ` `} ` ` `  `// Function to compute k maximum overlapping sub- ` `// array sums ` `void` `kMaxOvSubArray(vector<``int``> arr, ``int` `k) ` `{ ` `    ``int` `n = arr.size(); ` ` `  `    ``// Compute the prefix sum of the input array. ` `    ``vector<``int``> pre_sum = prefix_sum(arr, n); ` ` `  `    ``// Set all the elements of mini as +infinite ` `    ``// except 0th. Set the 0th element as 0. ` `    ``vector<``int``> mini(k, numeric_limits<``int``>::max()); ` `    ``mini = 0; ` ` `  `    ``// Set all the elements of maxi as -infinite. ` `    ``vector<``int``> maxi(k, numeric_limits<``int``>::min()); ` ` `  `    ``// Initialize cand array. ` `    ``vector<``int``> cand(k); ` ` `  `    ``// For each element of the prefix_sum array do: ` `    ``// compute the cand array. ` `    ``// take k maximum values from maxi and cand ` `    ``// using maxmerge function. ` `    ``// insert prefix_sum[i] to mini array if needed ` `    ``// using insertMini function. ` `    ``for` `(``int` `i = 0; i < n; i++) { ` `        ``for` `(``int` `j = 0; j < k; j++) { ` `             ``if``(pre_sum[i] < 0 && mini[j]==numeric_limits<``int``>::max()) ` `           ``cand[j]=(-pre_sum[i])-mini[j]; ` `         ``else` `cand[j] = pre_sum[i] - mini[j]; ` `        ``} ` `        ``maxMerge(maxi, cand); ` `        ``insertMini(mini, pre_sum[i]); ` `    ``} ` ` `  `    ``// Elements of maxi array is the k ` `    ``// maximum overlapping sub-array sums. ` `    ``// Print out the elements of maxi array. ` `    ``for` `(``int` `ele : maxi) ` `        ``cout << ele << ``" "``; ` `    ``cout << endl; ` `} ` ` `  `// Driver Program ` `int` `main() ` `{ ` `    ``// Test case 1 ` `    ``vector<``int``> arr1 = { 4, -8, 9, -4, 1, -8, -1, 6 }; ` `    ``int` `k1 = 4; ` `    ``kMaxOvSubArray(arr1, k1); ` ` `  `    ``// Test case 2 ` `    ``vector<``int``> arr2 = { -2, -3, 4, -1, -2, 1, 5, -3 }; ` `    ``int` `k2 = 3; ` `    ``kMaxOvSubArray(arr2, k2); ` `    ``return` `0; ` `} `

## Python3

 `# Python program to find out k maximum sum of ` `# overlapping sub-arrays ` ` `  `# Function to compute prefix-sum of the input array ` `def` `prefix_sum(arr, n): ` `    ``pre_sum ``=` `list``() ` `    ``pre_sum.append(arr[``0``]) ` `    ``for` `i ``in` `range``(``1``, n): ` `        ``pre_sum.append(pre_sum[i``-``1``] ``+` `arr[i]) ` `    ``return` `pre_sum ` ` `  `# Update maxi by k maximum values from maxi and cand ` `def` `maxMerge(maxi, cand): ` ` `  `    ``# Here cand and maxi arrays are in non-increasing ` `    ``# order beforehand. Now, j is the index of the ` `    ``# next cand element and i is the index of next ` `    ``# maxi element. Traverse through maxi array. ` `    ``# If cand[j] > maxi[i] insert cand[j] at the ith ` `    ``# position in the maxi array and remove the minimum ` `    ``# element of the maxi array i.e. the last element ` `    ``# and increase j by 1 i.e. take the next element ` `    ``# from cand. ` `    ``k ``=` `len``(maxi) ` `    ``j ``=` `0` `    ``for` `i ``in` `range``(k): ` `        ``if` `(cand[j] > maxi[i]): ` `            ``maxi.insert(i, cand[j]) ` `            ``del` `maxi[``-``1``] ` `            ``j ``+``=` `1` ` `  `# Insert prefix_sum[i] to mini array if needed ` `def` `insertMini(mini, pre_sum): ` ` `  `    ``# Traverse the mini array from left to right. ` `    ``# If prefix_sum[i] is less than any element ` `    ``# then insert prefix_sum[i] at that position ` `    ``# and delete maximum element of the mini array ` `    ``# i.e. the rightmost element from the array. ` `    ``k ``=` `len``(mini) ` `    ``for` `i ``in` `range``(k): ` `        ``if` `(pre_sum < mini[i]): ` `            ``mini.insert(i, pre_sum) ` `            ``del` `mini[``-``1``] ` `            ``break` ` `  `# Function to compute k maximum overlapping sub-array sums ` `def` `kMaxOvSubArray(arr, k): ` `    ``n ``=` `len``(arr) ` ` `  `    ``# Compute the prefix sum of the input array. ` `    ``pre_sum ``=` `prefix_sum(arr, n) ` ` `  `    ``# Set all the elements of mini as + infinite ` `    ``# except 0th. Set the 0th element as 0. ` `    ``mini ``=` `[``float``(``'inf'``) ``for` `i ``in` `range``(k)] ` `    ``mini[``0``] ``=` `0` ` `  `    ``# Set all the elements of maxi as -infinite. ` `    ``maxi ``=` `[``-``float``(``'inf'``) ``for` `i ``in` `range``(k)] ` ` `  `    ``# Initialize cand array. ` `    ``cand ``=` `[``0` `for` `i ``in` `range``(k)] ` ` `  `    ``# For each element of the prefix_sum array do: ` `    ``# compute the cand array. ` `    ``# take k maximum values from maxi and cand ` `    ``# using maxmerge function. ` `    ``# insert prefix_sum[i] to mini array if needed ` `    ``# using insertMini function. ` `    ``for` `i ``in` `range``(n): ` `        ``for` `j ``in` `range``(k): ` `            ``cand[j] ``=` `pre_sum[i] ``-` `mini[j] ` `        ``maxMerge(maxi, cand) ` `        ``insertMini(mini, pre_sum[i]) ` ` `  `    ``# Elements of maxi array is the k ` `    ``# maximum overlapping sub-array sums. ` `    ``# Print out the elements of maxi array. ` `    ``for` `ele ``in` `maxi: ` `        ``print``(ele, end ``=` `' '``) ` `    ``print``('') ` ` `  `# Driver Program ` `# Test case 1 ` `arr1 ``=` `[``4``, ``-``8``, ``9``, ``-``4``, ``1``, ``-``8``, ``-``1``, ``6``] ` `k1 ``=` `4` `kMaxOvSubArray(arr1, k1) ` ` `  `# Test case 2 ` `arr2 ``=` `[``-``2``, ``-``3``, ``4``, ``-``1``, ``-``2``, ``1``, ``5``, ``-``3``] ` `k2 ``=` `3` `kMaxOvSubArray(arr2, k2) `

Output:

```9 6 6 5
7 6 5
```

Time Complexity: The ‘insertMini’ and ‘maxMerge’ functions runs in O(k) time and it takes O(k) time to update the ‘cand’ array. We do this process for n times. Hence, the overall time complexity is O(k*n).

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.

My Personal Notes arrow_drop_up I am an undergrad at IIEST Shibpur love to code and solve algorithm data structure problems

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.

Improved By : getLost, rohitrjn629