 Open in App
Not now

# Subarray whose sum is closest to K

• Difficulty Level : Hard
• Last Updated : 30 Aug, 2022

Given an array of positive and negative integers and an integer K. The task is to find the subarray which has its sum closest to k. In case of multiple answers, print anyone.

Note: Closest here means abs(sum-k) should be minimal.

Examples:

Input: a[] = { -5, 12, -3, 4, -15, 6, 1 }, K = 2
Output:
The subarray {-3, 4} or {1} has sum = 1 which is the closest to K.

Input: a[] = { 2, 2, -1, 5, -3, -2 }, K = 7
Output:
Here the output can be 6 or 8
The subarray {2, 2, -1, 5} gives sum as 8 which has abs(8-7) = 1 which is same as that of the subarray {2, -1, 5} which has abs(6-7) = 1.

A naive approach is to check for all possible subarray sum using prefix sum. The complexity in that case will be O(N2).

An efficient solution will be to use C++ STL set and binary search to solve the following problem. Follow the below algorithm to solve the above problem.

• Initially insert the first element in the set container.
• Initialize the answer sum as first element and difference as abs(A0-k).
• Iterate for all array elements from 1 to N and keep adding the elements to prefix sum at each step to the set container.
• At every iteration, since the prefix sum is already there, we just need to subtract the sum of some elements from beginning to get the sum of any subarray. The greedy way will be to subtract the sum of the subarray which takes the sum closest to K.
• Using binary search (lower_bound() function can be used) find the sum of subarray from beginning which is closest to (prefix-k) as the subtraction of that number from prefix sum will give the subarray sum which is closest to K till that iteration.
• Also check for the index before which lower_bound() returns, since the sum can either be greater or lesser than K.
• If the lower_bound returns no such element, then the current prefix sum is compared and updated if it was lesser than the previous computed sum.

Below is the implementation of the above approach.

## C++

 `// C++ program to find the` `// sum of subarray whose sum is` `// closest to K` `#include ` `using` `namespace` `std;`   `// Function to find the sum of subarray` `// whose sum is closest to K` `int` `closestSubarraySumToK(``int` `a[], ``int` `n, ``int` `k)` `{`   `    ``// Declare a set` `    ``set<``int``> s;`   `    ``// initially consider the` `    ``// first subarray as the first` `    ``// element in the array` `    ``int` `presum = a;`   `    ``// insert` `    ``s.insert(a);`   `    ``// Initially let this difference` `    ``// be the minimum` `    ``int` `mini = ``abs``(a - k);`   `    ``// let this be the sum` `    ``// of the subarray` `    ``// to be searched initially` `    ``int` `sum = presum;`   `    ``// iterate for all the array elements` `    ``for` `(``int` `i = 1; i < n; i++) {`   `        ``// calculate the prefix sum` `        ``presum += a[i];`   `        ``// find the closest subarray` `        ``// sum to by using lower_bound` `        ``auto` `it = s.lower_bound(presum - k);`   `        ``// if it is the first element` `        ``// in the set` `        ``if` `(it == s.begin()) {`   `            ``// get the prefix sum till start` `            ``// of the subarray` `            ``int` `diff = *it;`   `            ``// if the subarray sum is closest to K` `            ``// than the previous one` `            ``if` `(``abs``((presum - diff) - k) < mini) {`   `                ``// update the minimal difference` `                ``mini = ``abs``((presum - diff) - k);`   `                ``// update the sum` `                ``sum = presum - diff;` `            ``}` `              `  `            ``if``(``abs``(presum - k) < mini){` `              ``// update the minimal difference` `                  ``mini = ``abs``((presum - diff) - k);`   `                  ``// update the sum` `                  ``sum = presum - diff;` `              ``}` `        ``}`   `        ``// if the difference is` `        ``// present in between` `        ``else` `if` `(it != s.end()) {`   `            ``// get the prefix sum till start` `            ``// of the subarray` `            ``int` `diff = *it;`   `            ``// if the subarray sum is closest to K` `            ``// than the previous one` `            ``if` `(``abs``((presum - diff) - k) < mini) {`   `                ``// update the minimal difference` `                ``mini = ``abs``((presum - diff) - k);`   `                ``// update the sum` `                ``sum = presum - diff;` `            ``}`   `            ``// also check for the one before that` `            ``// since the sum can be greater than` `            ``// or less than K also` `            ``it--;`   `            ``// get the prefix sum till start` `            ``// of the subarray` `            ``diff = *it;`   `            ``// if the subarray sum is closest to K` `            ``// than the previous one` `            ``if` `(``abs``((presum - diff) - k) < mini) {`   `                ``// update the minimal difference` `                ``mini = ``abs``((presum - diff) - k);`   `                ``// update the sum` `                ``sum = presum - diff;` `            ``}` `        ``}`   `        ``// if there exists no such prefix sum` `        ``// then the current prefix sum is` `        ``// checked and updated` `        ``else` `{`   `            ``// if the subarray sum is closest to K` `            ``// than the previous one` `            ``if` `(``abs``(presum - k) < mini) {`   `                ``// update the minimal difference` `                ``mini = ``abs``(presum - k);`   `                ``// update the sum` `                ``sum = presum;` `            ``}` `        ``}`   `        ``// insert the current prefix sum` `        ``s.insert(presum);` `    ``}`   `    ``return` `sum;` `}`   `// Driver Code` `int` `main()` `{` `    ``int` `a[] = { -5, 12, -3, 4, -15, 6, 1 };` `    ``int` `n = ``sizeof``(a) / ``sizeof``(a);` `    ``int` `k = 2;`   `    ``cout << closestSubarraySumToK(a, n, k);` `    ``return` `0;` `}`

## Java

 `// Java program to find the` `// sum of subarray whose sum is` `// closest to K` `import` `java.util.*;`   `class` `GFG{`   `  ``// Function to find the sum of subarray` `  ``// whose sum is closest to K` `  ``static` `int` `closestSubarraySumToK(``int` `a[], ``int` `n, ``int` `k)` `  ``{`   `    ``// Declare a set` `    ``TreeSet s = ``new` `TreeSet<>();`   `    ``// initially consider the` `    ``// first subarray as the first` `    ``// element in the array` `    ``int` `presum = a[``0``];`   `    ``// insert` `    ``s.add(a[``0``]);`   `    ``// Initially let this difference` `    ``// be the minimum` `    ``int` `mini = Math.abs(a[``0``] - k);`   `    ``// let this be the sum` `    ``// of the subarray` `    ``// to be searched initially` `    ``int` `sum = presum;`   `    ``// iterate for all the array elements` `    ``for` `(``int` `i = ``1``; i < n; i++) {`   `      ``// calculate the prefix sum` `      ``presum += a[i];`   `      ``// find the closest subarray` `      ``// sum to by using lower_bound` `      ``Integer it = s.lower(presum - k);`   `      ``// if it is the first element` `      ``// in the set` `      ``if` `(it == s.first()) {`   `        ``// get the prefix sum till start` `        ``// of the subarray` `        ``int` `diff = it;`   `        ``// if the subarray sum is closest to K` `        ``// than the previous one` `        ``if` `(Math.abs((presum - diff) - k) < mini) {`   `          ``// update the minimal difference` `          ``mini = Math.abs((presum - diff) - k);`   `          ``// update the sum` `          ``sum = presum - diff;` `        ``}` `      ``}`   `      ``// if the difference is` `      ``// present in between` `      ``else` `if` `(it == s.last()) {`   `        ``// get the prefix sum till start` `        ``// of the subarray` `        ``int` `diff = it;`   `        ``// if the subarray sum is closest to K` `        ``// than the previous one` `        ``if` `(Math.abs((presum - diff) - k) < mini) {`   `          ``// update the minimal difference` `          ``mini = Math.abs((presum - diff) - k);`   `          ``// update the sum` `          ``sum = presum - diff;` `        ``}`   `        ``// also check for the one before that` `        ``// since the sum can be greater than` `        ``// or less than K also` `        ``it--;`   `        ``// get the prefix sum till start` `        ``// of the subarray` `        ``diff = it;`   `        ``// if the subarray sum is closest to K` `        ``// than the previous one` `        ``if` `(Math.abs((presum - diff) - k) < mini) {`   `          ``// update the minimal difference` `          ``mini = Math.abs((presum - diff) - k);`   `          ``// update the sum` `          ``sum = presum - diff;` `        ``}` `      ``}`   `      ``// if there exists no such prefix sum` `      ``// then the current prefix sum is` `      ``// checked and updated` `      ``else` `{`   `        ``// if the subarray sum is closest to K` `        ``// than the previous one` `        ``if` `(Math.abs(presum - k) < mini) {`   `          ``// update the minimal difference` `          ``mini = Math.abs(presum - k);`   `          ``// update the sum` `          ``sum = presum+``1``;` `        ``}` `      ``}`   `      ``// insert the current prefix sum` `      ``s.add(presum);` `    ``}`   `    ``return` `sum;` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``int` `a[] = { -``5``, ``12``, -``3``, ``4``, -``15``, ``6``, ``1` `};` `    ``int` `n = a.length;` `    ``int` `k = ``2``;`   `    ``System.out.print(closestSubarraySumToK(a, n, k));` `  ``}` `}`   `// This code contributed by Rajput-Ji `

## Python3

 `# Python3 program to find the` `# sum of subarray whose sum is` `# closest to K` `import` `bisect`   `# Function to find the sum of subarray` `# whose sum is closest to K` `def` `closestSubarraySumToK(a , n , k):` `    `  `    ``# Declare a set` `    ``s ``=` `[]`   `    ``# initially consider the` `    ``# first subarray as the first` `    ``# element in the array` `    ``presum ``=` `a[``0``]`   `    ``# insert` `    ``s.append(a[``0``])`   `    ``# Initially let this difference` `    ``# be the minimum` `    ``mini ``=` `abs``(a[``0``] ``-` `k)`   `    ``# let this be the sum` `    ``# of the subarray` `    ``# to be searched initially` `    ``sum` `=` `presum`   `    ``# iterate for all the array elements` `    ``for` `i ``in` `range``(``1``, n):`   `        ``# calculate the prefix sum` `        ``presum ``+``=` `a[i]`   `        ``# find the closest subarray` `        ``# sum to by using lower_bound` `        ``it ``=` `bisect.bisect_left(s,presum ``-` `k)` `        `  `        ``if``(it ``=``=` `-``1``):` `            ``continue` `                `  `        ``#if it is the first element` `        ``# in the set` `        ``if` `(it ``=``=` `0``):`   `            ``#get the prefix sum till start` `            ``#of the subarray` `            ``diff ``=` `s[it]`   `            ``# if the subarray sum is closest to K` `            ``# than the previous one` `            ``if` `(``abs``((presum ``-` `diff) ``-` `k) < mini):`   `                ``# update the minimal difference` `                ``mini ``=` `abs``((presum ``-` `diff) ``-` `k)`   `                ``# update the sum` `                ``sum` `=` `presum ``-` `diff` `            `  `            ``if` `(``abs``(presum ``-` `k) < mini):` `                ``#update the minimal difference` `                ``mini ``=` `abs``((presum ``-` `diff) ``-` `k)` `                `  `                ``#update the sum` `                ``sum` `=` `presum ``-` `diff` `                `  `            `    `        ``# if the difference is` `        ``# present in between` `        ``elif` `(it !``=` `len``(s)):` `            `  `            ``# get the prefix sum till start` `            ``# of the subarray` `            ``diff ``=` `s[it]`   `            ``# if the subarray sum is closest to K` `            ``# than the previous one` `            ``if` `(``abs``((presum ``-` `diff) ``-` `k) < mini):`   `                ``# update the minimal difference` `                ``mini ``=` `abs``((presum ``-` `diff) ``-` `k)`   `                ``# update the sum` `                ``sum` `=` `presum ``-` `diff` `                `    `            ``# also check for the one before that` `            ``# since the sum can be greater than` `            ``# or less than K also` `            ``it ``-``=` `1`   `            ``# get the prefix sum till start` `            ``# of the subarray` `            ``diff ``=` `s[it]`   `            ``# if the subarray sum is closest to K` `            ``# than the previous one` `            ``if` `(``abs``((presum ``-` `diff) ``-` `k) < mini):`   `                ``# update the minimal difference` `                ``mini ``=` `abs``((presum ``-` `diff) ``-` `k)`   `                ``# update the sum` `                ``sum` `=` `presum ``-` `diff;`     `        ``# if there exists no such prefix sum` `        ``# then the current prefix sum is` `        ``# checked and updated` `        ``else` `:`   `            ``# if the subarray sum is closest to K` `            ``# than the previous one` `            ``if` `(``abs``(presum ``-` `k) < mini):`   `                ``# update the minimal difference` `                ``mini ``=` `abs``(presum ``-` `k)`   `                ``# update the sum` `                ``sum` `=` `presum ``+` `1``;`   `        ``# insert the current prefix sum` `        ``bisect.insort(s, presum)`   `    ``return` `sum`   `    `  `    `  `# Driver Code` `a ``=` `[ ``-``5``, ``12``, ``-``3``, ``4``, ``-``15``, ``6``, ``1` `]` `n ``=` `len``(a)` `k ``=` `2`   `print``(closestSubarraySumToK(a, n, k))`   `#This code is contributed by phasing17`

## C#

 `// C# program to find the` `// sum of subarray whose sum is` `// closest to K` `using` `System;` `using` `System.Linq;` `using` `System.Collections.Generic;`   `public` `class` `GFG {`   `  ``// Function to find the sum of subarray` `  ``// whose sum is closest to K` `  ``static` `int` `closestSubarraySumToK(``int` `[]a, ``int` `n, ``int` `k) {`   `    ``// Declare a set` `    ``SortedSet<``int``> s = ``new` `SortedSet<``int``>();`   `    ``// initially consider the` `    ``// first subarray as the first` `    ``// element in the array` `    ``int` `presum = a;`   `    ``// insert` `    ``s.Add(a);`   `    ``// Initially let this difference` `    ``// be the minimum` `    ``int` `mini = Math.Abs(a - k);`   `    ``// let this be the sum` `    ``// of the subarray` `    ``// to be searched initially` `    ``int` `sum = presum;`   `    ``// iterate for all the array elements` `    ``for` `(``int` `i = 1; i < n; i++) {`   `      ``// calculate the prefix sum` `      ``presum += a[i];`   `      ``// find the closest subarray` `      ``// sum to by using lower_bound` `      ``int` `it = lower_bound(s,presum - k);`   `      ``// if it is the first element` `      ``// in the set` `      ``if` `(it == s.First()) {`   `        ``// get the prefix sum till start` `        ``// of the subarray` `        ``int` `diff = it;`   `        ``// if the subarray sum is closest to K` `        ``// than the previous one` `        ``if` `(Math.Abs((presum - diff) - k) < mini) {`   `          ``// update the minimal difference` `          ``mini = Math.Abs((presum - diff) - k);`   `          ``// update the sum` `          ``sum = presum - diff;` `        ``}` `      ``}`   `      ``// if the difference is` `      ``// present in between` `      ``else` `if` `(it == s.Last()) {`   `        ``// get the prefix sum till start` `        ``// of the subarray` `        ``int` `diff = it;`   `        ``// if the subarray sum is closest to K` `        ``// than the previous one` `        ``if` `(Math.Abs((presum - diff) - k) < mini) {`   `          ``// update the minimal difference` `          ``mini = Math.Abs((presum - diff) - k);`   `          ``// update the sum` `          ``sum = presum - diff;` `        ``}`   `        ``// also check for the one before that` `        ``// since the sum can be greater than` `        ``// or less than K also` `        ``it--;`   `        ``// get the prefix sum till start` `        ``// of the subarray` `        ``diff = it;`   `        ``// if the subarray sum is closest to K` `        ``// than the previous one` `        ``if` `(Math.Abs((presum - diff) - k) < mini) {`   `          ``// update the minimal difference` `          ``mini = Math.Abs((presum - diff) - k);`   `          ``// update the sum` `          ``sum = presum - diff;` `        ``}` `      ``}`   `      ``// if there exists no such prefix sum` `      ``// then the current prefix sum is` `      ``// checked and updated` `      ``else` `{`   `        ``// if the subarray sum is closest to K` `        ``// than the previous one` `        ``if` `(Math.Abs(presum - k) < mini) {`   `          ``// update the minimal difference` `          ``mini = Math.Abs(presum - k);`   `          ``// update the sum` `          ``sum = presum + 1;` `        ``}` `      ``}`   `      ``// insert the current prefix sum` `      ``s.Add(presum);` `    ``}`   `    ``return` `sum-1;` `  ``}` `  ``public` `static` `int` `lower_bound(SortedSet<``int``> s, ``int` `val)` `  ``{` `    ``List<``int``> temp = ``new` `List<``int``>();` `    ``temp.AddRange(s);` `    ``temp.Sort();` `    ``temp.Reverse();`   `    ``if` `(temp.IndexOf(val) + 1 == temp.Count)` `      ``return` `-1;` `    ``return` `temp[temp.IndexOf(val) + 1];` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `Main(String[] args) {` `    ``int` `[]a = { -5, 12, -3, 4, -15, 6, 1 };` `    ``int` `n = a.Length;` `    ``int` `k = 2;`   `    ``Console.Write(closestSubarraySumToK(a, n, k));` `  ``}` `}`   `// This code is contributed by Rajput-Ji `

## Javascript

 ``

Output

`1`

Complexity Analysis:

• Time Complexity: O(N log N), where N represents the size of the given array.
• Auxiliary Space: O(N), where N represents the size of the given array.

My Personal Notes arrow_drop_up
Related Articles