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 it’s difference from K. 



Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to find sub-array whose
// sum shows the minimum deviation
#include <bits/stdc++.h>
using namespace std;
 
int* getSubArray(int arr[], int n, int K)
{
    int i = -1;
    int j = -1;
    int currSum = 0;
       
    // Starting index, ending index,
    // Deviation
    int* result = new int[3]{ i, j,
                              abs(K -
                              abs(currSum)) };
       
    // Iterate i and j to get all subarrays
    for(i = 0; i < n; i++)
    {
        currSum = 0;
           
        for(j = i; j < n; j++)
        {
            currSum += arr[j];
            int currDev = abs(K - abs(currSum));
               
            // Found sub-array with less sum
            if (currDev < result[2])
            {
                result[0] = i;
                result[1] = j;
                result[2] = currDev;
            }
               
            // Exactly same sum
            if (currDev == 0)
                return result;
        }
    }
    return result;
}
 
// Driver code  
int main()
{
    int arr[8] = { 15, -3, 5, 2, 7, 6, 34, -6 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int K = 50;
           
    // Array to store return values
    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;
}
 
// This code is contributed by divyeshrabadiya07

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java code to find sub-array whose
// sum shows the minimum deviation
class GFG{
     
public static int[] getSubArray(int[] arr,
                                int n,int K)
{
    int i = -1;
    int j = -1;
    int currSum = 0;
     
    // Starting index, ending index, Deviation
    int [] result = { i, j,
                      Math.abs(K -
                      Math.abs(currSum)) };
     
    // Iterate i and j to get all subarrays
    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));
             
            // Found sub-array with less sum
            if(currDev < result[2])
            {
                result[0] = i;
                result[1] = j;
                result[2] = currDev;
            }
             
            // Exactly same sum
            if(currDev == 0)
                return result;
        }
    }
    return result;
}
 
// Driver Code
public static void main(String[] args)
{
    int[] arr = { 15, -3, 5, 2, 7, 6, 34, -6 };
    int n = arr.length;
    int K = 50;
         
    // Array to store return values
    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] + " ");
    }
}
}
 
// This code is contributed by dadimadhav

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python Code to find sub-array whose
# sum shows the minimum deviation
 
def getSubArray(arr, n, K):
    i = -1
    j = -1
    currSum = 0
    # starting index, ending index, Deviation
    result = [i, j, abs(K-abs(currSum))]
     
    # iterate i and j to get all subarrays
    for i in range(0, n):
         
        currSum = 0
         
        for j in range(i, n):
            currSum += arr[j]
            currDev = abs(K-abs(currSum))
             
            # found sub-array with less sum
            if (currDev < result[2]):
                result = [i, j, currDev]
                 
            # exactly same sum
            if (currDev == 0):
                return result
    return result
     
# Driver Code
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()

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# code to find sub-array whose
// sum shows the minimum deviation
using System;
 
class GFG{
     
public static int[] getSubArray(int[] arr,
                                int n, int K)
{
    int i = -1;
    int j = -1;
    int currSum = 0;
     
    // Starting index, ending index, Deviation
    int [] result = { i, j,
                      Math.Abs(K -
                      Math.Abs(currSum)) };
     
    // Iterate i and j to get all subarrays
    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));
             
            // Found sub-array with less sum
            if (currDev < result[2])
            {
                result[0] = i;
                result[1] = j;
                result[2] = currDev;
            }
             
            // Exactly same sum
            if (currDev == 0)
                return result;
        }
    }
    return result;
}
 
// Driver Code
public static void Main(string[] args)
{
    int[] arr = { 15, -3, 5, 2, 7, 6, 34, -6 };
    int n = arr.Length;
    int K = 50;
         
    // Array to store return values
    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] + " ");
    }
}
}
 
// This code is contributed by rutvik_56

chevron_right


Output: 

-3 5 2 7 6 34

 

Time Complexity: O(N^2)

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: 

Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python Code to find non-negative
# sub-array whose sum shows minimum deviation
# This works only if all elements
# in array are non-negative
 
 
# function to return the index
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):
         
        # Add Last element tp currSum
        currSum += arr[j]
         
        # Save Difference of previous Iteration
        prevDif = currDif
         
        # Calculate new Difference
        currDif = K - abs(currSum)
         
        # When the Sum exceeds K
        if(currDif <= 0):
            if abs(currDif) < abs(prevDif):
                 
            # Current Difference greater in magnitude
            # Store Temporary Result
                resultTmp = [i, j, currDif]
            else:
                 
            # Diffence in Previous was lesser
            # In previous, Right index = j-1
                resultTmp = [i, j-1, prevDif]
                 
            # In next iteration, Left Index Increases
            # but Right Index remains the Same
            # Update currSum and i Accordingly
            currSum -= (arr[i]+arr[j])
             
            i += 1
         
        # Case to simply increase Right Index
        else:
            resultTmp = [i, j, currDif]
            j += 1
             
        if(abs(resultTmp[2]) < abs(result[2])):
        # Check if lesser deviation found
            result = resultTmp
             
    return result
 
# Driver Code
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()

chevron_right


Output: 

-3 5 2 7 6 34

 

Time Complexity: O(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

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.