Subarray whose absolute sum is closest to K
Given an array of n elements and an integer K, the task is to find the subarray with minimum value of ||a[i] + a[i + 1] + ……. a[j]| – K|. In other words, find the contiguous sub-array whose sum of elements shows minimum deviation from K or the subarray whose absolute sum is closest to K.
Example
Input:: a[] = {1, 3, 7, 10}, K = 15
Output: Subarray {7, 10}
The contiguous sub-array [7, 10] shows minimum deviation of 2 from 15.
Input: a[] = {1, 2, 3, 4, 5, 6}, K = 6
Output: Subarray {1, 2, 3}
The contiguous sub-array [1, 2, 3] shows minimum deviation of 0 from 6.
A naive approach would be to check if the sum of each contiguous sub-array and its difference from K.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int * getSubArray( int arr[], int n, int K)
{
int i = -1;
int j = -1;
int currSum = 0;
int * result = new int [3]{ i, j,
abs (K -
abs (currSum)) };
for (i = 0; i < n; i++)
{
currSum = 0;
for (j = i; j < n; j++)
{
currSum += arr[j];
int currDev = abs (K - abs (currSum));
if (currDev < result[2])
{
result[0] = i;
result[1] = j;
result[2] = currDev;
}
if (currDev == 0)
return result;
}
}
return result;
}
int main()
{
int arr[8] = { 15, -3, 5, 2, 7, 6, 34, -6 };
int n = sizeof (arr) / sizeof (arr[0]);
int K = 50;
int * ans = getSubArray(arr, n, K);
if (ans[0] == -1)
{
cout << "The empty array shows "
<< "minimum Deviation" ;
}
else
{
for ( int i = ans[0]; i <= ans[1]; i++)
cout << arr[i] << " " ;
}
return 0;
}
|
Java
class GFG{
public static int [] getSubArray( int [] arr,
int n, int K)
{
int i = - 1 ;
int j = - 1 ;
int currSum = 0 ;
int [] result = { i, j,
Math.abs(K -
Math.abs(currSum)) };
for (i = 0 ; i < n; i++)
{
currSum = 0 ;
for (j = i; j < n; j++)
{
currSum += arr[j];
int currDev = Math.abs(K -
Math.abs(currSum));
if (currDev < result[ 2 ])
{
result[ 0 ] = i;
result[ 1 ] = j;
result[ 2 ] = currDev;
}
if (currDev == 0 )
return result;
}
}
return result;
}
public static void main(String[] args)
{
int [] arr = { 15 , - 3 , 5 , 2 , 7 , 6 , 34 , - 6 };
int n = arr.length;
int K = 50 ;
int [] ans = getSubArray(arr, n, K);
if (ans[ 0 ] == - 1 )
{
System.out.println( "The empty array " +
"shows minimum Deviation" );
}
else
{
for ( int i = ans[ 0 ]; i <= ans[ 1 ]; i++)
System.out.print(arr[i] + " " );
}
}
}
|
Python
def getSubArray(arr, n, K):
i = - 1
j = - 1
currSum = 0
result = [i, j, abs (K - abs (currSum))]
for i in range ( 0 , n):
currSum = 0
for j in range (i, n):
currSum + = arr[j]
currDev = abs (K - abs (currSum))
if (currDev < result[ 2 ]):
result = [i, j, currDev]
if (currDev = = 0 ):
return result
return result
def main():
arr = [ 15 , - 3 , 5 , 2 , 7 , 6 , 34 , - 6 ]
n = len (arr)
K = 50
[i, j, minDev] = getSubArray(arr, n, K)
if (i = = - 1 ):
print ( "The empty array shows minimum Deviation" )
return 0
for i in range (i, j + 1 ):
print arr[i],
main()
|
C#
using System;
class GFG{
public static int [] getSubArray( int [] arr,
int n, int K)
{
int i = -1;
int j = -1;
int currSum = 0;
int [] result = { i, j,
Math.Abs(K -
Math.Abs(currSum)) };
for (i = 0; i < n; i++)
{
currSum = 0;
for (j = i; j < n; j++)
{
currSum += arr[j];
int currDev = Math.Abs(K -
Math.Abs(currSum));
if (currDev < result[2])
{
result[0] = i;
result[1] = j;
result[2] = currDev;
}
if (currDev == 0)
return result;
}
}
return result;
}
public static void Main( string [] args)
{
int [] arr = { 15, -3, 5, 2, 7, 6, 34, -6 };
int n = arr.Length;
int K = 50;
int [] ans = getSubArray(arr, n, K);
if (ans[0] == -1)
{
Console.Write( "The empty array " +
"shows minimum Deviation" );
}
else
{
for ( int i = ans[0]; i <= ans[1]; i++)
Console.Write(arr[i] + " " );
}
}
}
|
Javascript
<script>
function getSubArray(arr, n, K)
{
let i = -1;
let j = -1;
let currSum = 0;
let result = [ i, j,
Math.abs(K -
Math.abs(currSum)) ];
for (i = 0; i < n; i++)
{
currSum = 0;
for (j = i; j < n; j++)
{
currSum += arr[j];
let currDev = Math.abs(K -
Math.abs(currSum));
if (currDev < result[2])
{
result[0] = i;
result[1] = j;
result[2] = currDev;
}
if (currDev == 0)
return result;
}
}
return result;
}
let arr = [ 15, -3, 5, 2, 7, 6, 34, -6 ];
let n = arr.length;
let K = 50;
let ans = getSubArray(arr, n, K);
if (ans[0] == -1)
{
document.write( "The empty array " +
"shows minimum Deviation" );
}
else
{
for (let i = ans[0]; i <= ans[1]; i++)
document.write(arr[i] + " " );
}
</script>
|
Complexity Analysis:
- Time Complexity: O(N²)
- Auxiliary Space: O(1)
Efficient Approach:
If the array only consists of non-negative integers, use the sliding window technique to improve the calculation time for sum in each iteration. The sliding window technique reduces the complexity by calculating the new sub-array sum using the previous sub-array sum. Increase the right index till the difference (K-sum) is greater than zero. The first sub-array with negative (K-sum) is considered, and the next sub-array is with left index = i+1(where i is the current right index).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Pair
{
int f, s, t;
Pair( int f, int s, int t)
{
this ->f = f;
this ->s = s;
this ->t = t;
}
};
Pair* getSubArray( int *arr, int n, int K)
{
int currSum = 0;
int prevDif = 0;
int currDif = 0;
Pair *result = new Pair(
-1, -1, abs (K - abs (currSum)));
Pair *resultTmp = result;
int i = 0;
int j = 0;
while (i<= j && j<n)
{
currSum += arr[j];
prevDif = currDif;
currDif = K - abs (currSum);
if (currDif <= 0)
{
if ( abs (currDif) < abs (prevDif))
{
resultTmp = new Pair(i, j, currDif);
}
else
{
resultTmp = new Pair(i, j - 1, prevDif);
currSum -= (arr[i] + arr[j]);
i += 1;
}
}
else
{
resultTmp = new Pair(i, j, currDif);
j += 1;
}
if ( abs (resultTmp->t) < abs (result->t))
{
result = resultTmp;
}
}
return result;
}
int main()
{
int arr[] = { 15, -3, 5, 2, 7, 6, 34, -6 };
int n = sizeof (arr) / sizeof (arr[0]);
int K = 50;
Pair *tmp = getSubArray(arr, n, K);
int i = tmp->f;
int j = tmp->s;
int minDev = tmp->t;
if (i == -1)
{
cout << "The empty array shows minimum Deviation"
<< endl;
return 0;
}
for ( int k = i + 1; k < j + 1; k++)
{
cout << arr[k] << " " ;
}
return 0;
}
|
Java
import java.util.*;
class GFG{
static class Pair
{
int f, s, t;
Pair( int f, int s, int t)
{
this .f = f;
this .s = s;
this .t = t;
}
};
static Pair getSubArray( int []arr, int n, int K)
{
int currSum = 0 ;
int prevDif = 0 ;
int currDif = 0 ;
Pair result = new Pair(
- 1 , - 1 , Math.abs(K - Math.abs(currSum)));
Pair resultTmp = result;
int i = 0 ;
int j = 0 ;
while (i<= j && j<n)
{
currSum += arr[j];
prevDif = currDif;
currDif = K - Math.abs(currSum);
if (currDif <= 0 )
{
if (Math.abs(currDif) < Math.abs(prevDif))
{
resultTmp = new Pair(i, j, currDif);
}
else
{
resultTmp = new Pair(i, j - 1 , prevDif);
currSum -= (arr[i] + arr[j]);
i += 1 ;
}
}
else
{
resultTmp = new Pair(i, j, currDif);
j += 1 ;
}
if (Math.abs(resultTmp.t) < Math.abs(result.t))
{
result = resultTmp;
}
}
return result;
}
public static void main(String[] args)
{
int arr[] = { 15 , - 3 , 5 , 2 , 7 , 6 , 34 , - 6 };
int n = arr.length;
int K = 50 ;
Pair tmp = getSubArray(arr, n, K);
int i = tmp.f;
int j = tmp.s;
int minDev = tmp.t;
if (i == - 1 )
{
System.out.print( "The empty array shows minimum Deviation"
+ "\n" );
return ;
}
for ( int k = i + 1 ; k < j + 1 ; k++)
{
System.out.print(arr[k]+ " " );
}
}
}
|
Python
def getSubArray(arr, n, K):
currSum = 0
prevDif = 0
currDif = 0
result = [ - 1 , - 1 , abs (K - abs (currSum))]
resultTmp = result
i = 0
j = 0
while (i< = j and j<n):
currSum + = arr[j]
prevDif = currDif
currDif = K - abs (currSum)
if (currDif < = 0 ):
if abs (currDif) < abs (prevDif):
resultTmp = [i, j, currDif]
else :
resultTmp = [i, j - 1 , prevDif]
currSum - = (arr[i] + arr[j])
i + = 1
else :
resultTmp = [i, j, currDif]
j + = 1
if ( abs (resultTmp[ 2 ]) < abs (result[ 2 ])):
result = resultTmp
return result
def main():
arr = [ 15 , - 3 , 5 , 2 , 7 , 6 , 34 , - 6 ]
n = len (arr)
K = 50
[i, j, minDev] = getSubArray(arr, n, K)
if (i = = - 1 ):
print ( "The empty array shows minimum Deviation" )
return 0
for i in range (i, j + 1 ):
print arr[i],
main()
|
C#
using System;
public class GFG{
class Pair
{
public int f, s, t;
public Pair( int f, int s, int t)
{
this .f = f;
this .s = s;
this .t = t;
}
};
static Pair getSubArray( int []arr, int n, int K)
{
int currSum = 0;
int prevDif = 0;
int currDif = 0;
Pair result = new Pair(
-1, -1, Math.Abs(K - Math.Abs(currSum)));
Pair resultTmp = result;
int i = 0;
int j = 0;
while (i <= j && j < n)
{
currSum += arr[j];
prevDif = currDif;
currDif = K - Math.Abs(currSum);
if (currDif <= 0)
{
if (Math.Abs(currDif) < Math.Abs(prevDif))
{
resultTmp = new Pair(i, j, currDif);
}
else
{
resultTmp = new Pair(i, j - 1, prevDif);
currSum -= (arr[i] + arr[j]);
i += 1;
}
}
else
{
resultTmp = new Pair(i, j, currDif);
j += 1;
}
if (Math.Abs(resultTmp.t) < Math.Abs(result.t))
{
result = resultTmp;
}
}
return result;
}
public static void Main(String[] args)
{
int []arr = { 15, -3, 5, 2, 7, 6, 34, -6 };
int n = arr.Length;
int K = 50;
Pair tmp = getSubArray(arr, n, K);
int i = tmp.f;
int j = tmp.s;
int minDev = tmp.t;
if (i == -1)
{
Console.Write( "The empty array shows minimum Deviation"
+ "\n" );
return ;
}
for ( int k = i + 1; k < j + 1; k++)
{
Console.Write(arr[k]+ " " );
}
}
}
|
Javascript
class Pair {
constructor(f, s, t) {
this .f = f;
this .s = s;
this .t = t;
}
}
function getSubArray(arr, n, K) {
let currSum = 0;
let prevDif = 0;
let currDif = 0;
let result = new Pair(-1, -1, Math.abs(K - Math.abs(currSum)));
let resultTmp = result;
let i = 0;
let j = 0;
while (i <= j && j < n) {
currSum += arr[j];
prevDif = currDif;
currDif = K - Math.abs(currSum);
if (currDif <= 0) {
if (Math.abs(currDif) < Math.abs(prevDif)) {
resultTmp = new Pair(i, j, currDif);
} else {
resultTmp = new Pair(i, j - 1, prevDif);
currSum -= (arr[i] + arr[j]);
i += 1;
}
}
else {
resultTmp = new Pair(i, j, currDif);
j += 1;
}
if (Math.abs(resultTmp.t) < Math.abs(result.t)) {
result = resultTmp;
}
}
return result;
}
let arr = [ 15, -3, 5, 2, 7, 6, 34, -6 ];
let n = arr.length;
let K = 50;
let tmp = getSubArray(arr, n, K);
let i = tmp.f;
let j = tmp.s;
let minDev = tmp.t;
if (i == -1) {
console.log( "The empty array shows minimum Deviation" );
}
for (let k = i + 1; k < j + 1; k++) {
console.log(arr[k] + " " );
}
|
Complexity Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Last Updated :
17 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...