Given an array of integers. Write a program to find the K-th largest sum of contiguous subarray within the array of numbers that has both negative and positive numbers.
Examples:
Input: a[] = {20, -5, -1}, K = 3
Output: 14
Explanation: All sum of contiguous subarrays are (20, 15, 14, -5, -6, -1)
so the 3rd largest sum is 14.
Input: a[] = {10, -10, 20, -40}, k = 6
Output: -10
Explanation: The 6th largest sum among
sum of all contiguous subarrays is -10.
Brute force Approach: Store all the contiguous sums in another array and sort it and print the Kth largest. But in the case of the number of elements being large, the array in which we store the contiguous sums will run out of memory as the number of contiguous subarrays will be large (quadratic order)
C++
#include <bits/stdc++.h>
using namespace std;
int kthLargestSum( int arr[], int N, int K)
{
vector< int > result;
for ( int i = 0; i < N; i++) {
int sum = 0;
for ( int j = i; j < N; j++) {
sum += arr[j];
result.push_back(sum);
}
}
sort(result.begin(), result.end(), greater< int >());
return result[K - 1];
}
int main()
{
int a[] = { 20, -5, -1 };
int N = sizeof (a) / sizeof (a[0]);
int K = 3;
cout << kthLargestSum(a, N, K);
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int kthLargestSum( int arr[], int N, int K)
{
ArrayList<Integer> result = new ArrayList<>();
for ( int i = 0 ; i < N; i++) {
int sum = 0 ;
for ( int j = i; j < N; j++) {
sum += arr[j];
result.add(sum);
}
}
Collections.sort(result,
Collections.reverseOrder());
return result.get(K - 1 );
}
public static void main(String[] args)
{
int a[] = { 20 , - 5 , - 1 };
int N = a.length;
int K = 3 ;
System.out.println(kthLargestSum(a, N, K));
}
}
|
Python3
def kthLargestSum(arr, N, K):
result = []
for i in range (N):
sum = 0
for j in range (i, N):
sum + = arr[j]
result.append( sum )
result.sort(reverse = True )
return result[K - 1 ]
a = [ 20 , - 5 , - 1 ]
N = len (a)
K = 3
print (kthLargestSum(a, N, K))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int kthLargestSum( int [] arr, int N, int K)
{
List< int > result = new List< int >();
for ( int i = 0; i < N; i++) {
int sum = 0;
for ( int j = i; j < N; j++) {
sum += arr[j];
result.Add(sum);
}
}
result.Sort();
result.Reverse();
return result[K - 1];
}
public static void Main( string [] args)
{
int [] a = { 20, -5, -1 };
int N = a.Length;
int K = 3;
Console.WriteLine(kthLargestSum(a, N, K));
}
}
|
Javascript
function kthLargestSum(arr, N, K)
{
let result=[];
for (let i = 0; i < N; i++) {
let sum = 0;
for (let j = i; j < N; j++) {
sum += arr[j];
result.push(sum);
}
}
result.sort();
result.reverse();
return result[K - 1];
}
let a = [20, -5, -1 ];
let N = a.length;
let K = 3;
document.write(kthLargestSum(a, N, K));
|
Time Complexity: O(n2*log(n2))
Auxiliary Space: O(n)
Kth largest sum contiguous subarray using Min-Heap:
The key idea is to store the pre-sum of the array in a sum[] array. One can find the sum of contiguous subarray from index i to j as sum[j] – sum[i-1]. Now generate all possible contiguous subarray sums and push them into the Min-Heap only if the size of Min-Heap is less than K or the current sum is greater than the root of the Min-Heap. In the end, the root of the Min-Heap is the required answer
Follow the given steps to solve the problem using the above approach:
- Create a prefix sum array of the input array
- Create a Min-Heap that stores the subarray sum
- Iterate over the given array using the variable i such that 1 <= i <= N, here i denotes the starting point of the subarray
- Create a nested loop inside this loop using a variable j such that i <= j <= N, here j denotes the ending point of the subarray
- Calculate the sum of the current subarray represented by i and j, using the prefix sum array
- If the size of the Min-Heap is less than K, then push this sum into the heap
- Otherwise, if the current sum is greater than the root of the Min-Heap, then pop out the root and push the current sum into the Min-Heap
- Now the root of the Min-Heap denotes the Kth largest sum, Return it
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int kthLargestSum( int arr[], int N, int K)
{
int sum[N + 1];
sum[0] = 0;
sum[1] = arr[0];
for ( int i = 2; i <= N; i++)
sum[i] = sum[i - 1] + arr[i - 1];
priority_queue< int , vector< int >, greater< int > > Q;
for ( int i = 1; i <= N; i++) {
for ( int j = i; j <= N; j++) {
int x = sum[j] - sum[i - 1];
if (Q.size() < K)
Q.push(x);
else {
if (Q.top() < x) {
Q.pop();
Q.push(x);
}
}
}
}
return Q.top();
}
int main()
{
int a[] = { 10, -10, 20, -40 };
int N = sizeof (a) / sizeof (a[0]);
int K = 6;
cout << kthLargestSum(a, N, K);
return 0;
}
|
Java
import java.util.*;
class KthLargestSumSubArray {
static int kthLargestSum( int arr[], int N, int K)
{
int sum[] = new int [N + 1 ];
sum[ 0 ] = 0 ;
sum[ 1 ] = arr[ 0 ];
for ( int i = 2 ; i <= N; i++)
sum[i] = sum[i - 1 ] + arr[i - 1 ];
PriorityQueue<Integer> Q
= new PriorityQueue<Integer>();
for ( int i = 1 ; i <= N; i++) {
for ( int j = i; j <= N; j++) {
int x = sum[j] - sum[i - 1 ];
if (Q.size() < K)
Q.add(x);
else {
if (Q.peek() < x) {
Q.poll();
Q.add(x);
}
}
}
}
return Q.poll();
}
public static void main(String[] args)
{
int a[] = new int [] { 10 , - 10 , 20 , - 40 };
int N = a.length;
int K = 6 ;
System.out.println(kthLargestSum(a, N, K));
}
}
|
Python3
import heapq
def kthLargestSum(arr, N, K):
sum = []
sum .append( 0 )
sum .append(arr[ 0 ])
for i in range ( 2 , N + 1 ):
sum .append( sum [i - 1 ] + arr[i - 1 ])
Q = []
heapq.heapify(Q)
for i in range ( 1 , N + 1 ):
for j in range (i, N + 1 ):
x = sum [j] - sum [i - 1 ]
if len (Q) < K:
heapq.heappush(Q, x)
else :
if Q[ 0 ] < x:
heapq.heappop(Q)
heapq.heappush(Q, x)
return Q[ 0 ]
if __name__ = = "__main__" :
a = [ 10 , - 10 , 20 , - 40 ]
N = len (a)
K = 6
print (kthLargestSum(a, N, K))
|
C#
using System;
using System.Collections.Generic;
public class KthLargestSumSubArray {
static int kthLargestSum( int [] arr, int N, int K)
{
int [] sum = new int [N + 1];
sum[0] = 0;
sum[1] = arr[0];
for ( int i = 2; i <= N; i++)
sum[i] = sum[i - 1] + arr[i - 1];
List< int > Q = new List< int >();
for ( int i = 1; i <= N; i++) {
for ( int j = i; j <= N; j++) {
int x = sum[j] - sum[i - 1];
if (Q.Count < K)
Q.Add(x);
else {
Q.Sort();
if (Q[0] < x) {
Q.RemoveAt(0);
Q.Add(x);
}
}
Q.Sort();
}
}
return Q[0];
}
public static void Main(String[] args)
{
int [] a = new int [] { 10, -10, 20, -40 };
int N = a.Length;
int K = 6;
Console.WriteLine(kthLargestSum(a, N, K));
}
}
|
JavaScript
function kthLargestSum(arr, n, k)
{
var sum = new Array(n + 1);
sum[0] = 0;
sum[1] = arr[0];
for ( var i = 2; i <= n; i++)
sum[i] = sum[i - 1] + arr[i - 1];
var Q = [];
for ( var i = 1; i <= n; i++)
{
for ( var j = i; j <= n; j++)
{
var x = sum[j] - sum[i - 1];
if (Q.length < k)
Q.push(x);
else
{
Q.sort();
if (Q[0] < x)
{
Q.pop();
Q.push(x);
}
}
Q.sort();
}
}
return Q[0];
}
var a = [ 10, -10, 20, -40 ];
var n = a.length;
var k = 6;
document.write(kthLargestSum(a, n, k));
|
Time Complexity: O(N2 log K)
Auxiliary Space: O(N), but this can be reduced to O(K) for min-heap and we can store the prefix sum array in the input array itself as it is of no use.
Kth largest sum contiguous subarray using Prefix Sum and Sorting approach:
The basic idea behind the Prefix Sum and Sorting approach is to create a prefix sum array and use it to calculate all possible subarray sums. The subarray sums are then sorted in decreasing order using the sort() function. Finally, the K-th largest sum of contiguous subarray is returned from the sorted vector of subarray sums.
Follow the Steps to implement the approach:
- Create a prefix sum array of the given array.
- Create a vector to store all possible subarray sums by subtracting prefix sums.
- Sort the vector of subarray sums in decreasing order using the sort() function.
- Return the K-th largest sum of contiguous subarray from the sorted vector of subarray sums.
Below is the implementation of the above approach:
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int kthLargestSum(vector< int >& arr, int k)
{
int n = arr.size();
vector< int > prefixSum(n + 1);
prefixSum[0] = 0;
for ( int i = 1; i <= n; i++) {
prefixSum[i] = prefixSum[i - 1] + arr[i - 1];
}
vector< int > subarraySums;
for ( int i = 0; i <= n; i++) {
for ( int j = i + 1; j <= n; j++) {
subarraySums.push_back(prefixSum[j]
- prefixSum[i]);
}
}
sort(subarraySums.begin(), subarraySums.end(),
greater< int >());
return subarraySums[k - 1];
}
int main()
{
vector< int > arr = { 10, -10, 20, -40 };
int k = 6;
cout << kthLargestSum(arr, k)
<< endl;
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class GFG {
public static int kthLargestSum(List<Integer> arr, int k) {
int n = arr.size();
List<Integer> prefixSum = new ArrayList<>(n + 1 );
prefixSum.add( 0 );
for ( int i = 1 ; i <= n; i++) {
prefixSum.add(prefixSum.get(i - 1 ) + arr.get(i - 1 ));
}
List<Integer> subarraySums = new ArrayList<>();
for ( int i = 0 ; i <= n; i++) {
for ( int j = i + 1 ; j <= n; j++) {
subarraySums.add(prefixSum.get(j) - prefixSum.get(i));
}
}
Collections.sort(subarraySums, Collections.reverseOrder());
return subarraySums.get(k - 1 );
}
public static void main(String[] args) {
List<Integer> arr = List.of( 10 , - 10 , 20 , - 40 );
int k = 6 ;
System.out.println(kthLargestSum(arr, k));
}
}
|
Python
import heapq
def kthLargestSum(arr, k):
n = len (arr)
prefixSum = [ 0 ] * (n + 1 )
for i in range ( 1 , n + 1 ):
prefixSum[i] = prefixSum[i - 1 ] + arr[i - 1 ]
subarraySums = []
heapq.heapify(subarraySums)
for i in range (n + 1 ):
for j in range (i + 1 , n + 1 ):
subarraySum = prefixSum[j] - prefixSum[i]
if len (subarraySums) < k:
heapq.heappush(subarraySums, subarraySum)
else :
if subarraySum > subarraySums[ 0 ]:
heapq.heapreplace(subarraySums, subarraySum)
return subarraySums[ 0 ]
if __name__ = = '__main__' :
arr = [ 10 , - 10 , 20 , - 40 ]
k = 6
print (kthLargestSum(arr, k))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG{
public static int kthLargestSum(List< int > arr, int k){
int n = arr.Count;
List< int > prefixSum = new List< int >(n + 1);
prefixSum.Add(0);
for ( int i = 1; i <= n; i++){
prefixSum.Add(prefixSum[i - 1] + arr[i - 1]);
}
List< int > subarraySums = new List< int >();
for ( int i = 0; i <= n; i++){
for ( int j = i + 1; j <= n; j++){
subarraySums.Add(prefixSum[j] - prefixSum[i]);
}
}
subarraySums.Sort();
subarraySums.Reverse();
return subarraySums[k - 1];
}
public static void Main( string [] args){
List< int > arr = new List< int > { 10, -10, 20, -40 };
int k = 6;
Console.WriteLine(kthLargestSum(arr, k));
}
}
|
Javascript
function kthLargestSum(arr, k) {
let n = arr.length;
let prefixSum = new Array(n + 1).fill(0);
prefixSum[0] = 0;
for (let i = 1; i <= n; i++) {
prefixSum[i] = prefixSum[i - 1] + arr[i - 1];
}
let subarraySums = [];
for (let i = 0; i <= n; i++) {
for (let j = i + 1; j <= n; j++) {
subarraySums.push(prefixSum[j] - prefixSum[i]);
}
}
subarraySums.sort((a, b) => b - a);
return subarraySums[k - 1];
}
let arr = [10, -10, 20, -40];
let k = 6;
console.log(kthLargestSum(arr, k));
|
Time Complexity: O(n^2 log n) ,The time complexity of the above code for the Prefix Sum and Sorting approach is O(n^2logn), where n is the size of the input array. This is due to the nested loop used to calculate all possible subarray sums and the sort() function used to sort the vector of subarray sums.
Auxiliary Space: O(n^2), The auxiliary space complexity of the above code is O(n). This is due to the creation of the prefix sum array(O(n)) and the vector to store all possible subarray sums(O(n^2))
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
29 Nov, 2023
Like Article
Save Article