Find the Sub-array with sum closest to 0 - GeeksforGeeks

17 Dec, 2021
Given an array of both positive and negative numbers, the task is to find out the subarray whose sum is closest to 0. There can be multiple such subarrays, we need to output just 1 of them. Examples:  
Input : arr[] = {-1, 3, 2, -5, 4}
Output : 1, 3
Subarray from index 1 to 3 has sum closest to 0 i.e.
3 + 2 + -5 = 0

Input : {2, -5, 4, -6, 3} 
Output : 0, 2
2 + -5 + 4 = 1 closest to 0
Asked in : Microsoft 
A Naive approach is to consider all subarrays one by one and update indexes of subarray with sum closest to 0.  
C++
Java
Python3
C#
Javascript
// C++ program to find subarray with// sum closest to 0#include <bits/stdc++.h>using namespace std; // Function to find the subarraypair<int, int> findSubArray(int arr[], int n){     int start, end, min_sum = INT_MAX;     // Pick a starting point    for (int i = 0; i < n; i++) {         // Consider current starting point        // as a subarray and update minimum        // sum and subarray indexes        int curr_sum = arr[i];        if (min_sum > abs(curr_sum)) {            min_sum = abs(curr_sum);            start = i;            end = i;        }         // Try all subarrays starting with i        for (int j = i + 1; j < n; j++) {            curr_sum = curr_sum + arr[j];             // update minimum sum            // and subarray indexes            if (min_sum > abs(curr_sum)) {                min_sum = abs(curr_sum);                start = i;                end = j;            }        }    }     // Return starting and ending indexes    pair<int, int> p = make_pair(start, end);    return p;} // Drivers codeint main(){    int arr[] = { 2, -5, 4, -6, -3 };    int n = sizeof(arr) / sizeof(arr[0]);     pair<int, int> point = findSubArray(arr, n);    cout << "Subarray starting from ";    cout << point.first << " to " << point.second;    return 0;}
// Java program to find subarray with// sum closest to 0 class GFG{     static class Pair    {         int first, second;        public Pair(int first, int second)        {            this.first = first;            this.second = second;        }     }         // Function to find the subarray    static Pair findSubArray(int arr[], int n)    {         int start = 0, end = 0, min_sum = Integer.MAX_VALUE;         // Pick a starting point        for (int i = 0; i < n; i++)        {             // Consider current starting point            // as a subarray and update minimum            // sum and subarray indexes            int curr_sum = arr[i];            if (min_sum > Math.abs(curr_sum))            {                min_sum = Math.abs(curr_sum);                start = i;                end = i;            }             // Try all subarrays starting with i            for (int j = i + 1; j < n; j++)            {                curr_sum = curr_sum + arr[j];                 // update minimum sum                // and subarray indexes                if (min_sum > Math.abs(curr_sum))                {                    min_sum = Math.abs(curr_sum);                    start = i;                    end = j;                }            }        }         // Return starting and ending indexes        Pair p = new Pair(start, end);        return p;    }     // Drivers code    public static void main(String[] args)    {        int arr[] = {2, -5, 4, -6, -3};        int n = arr.length;         Pair point = findSubArray(arr, n);        System.out.println("Subarray starting from "                + point.first + " to " + point.second);    }} // This code has been contributed by 29AjayKumar
# Python 3 program to find subarray with# sum closest to 0import sys # Function to find the subarraydef findSubArray(arr, n):    min_sum = sys.maxsize     # Pick a starting point    for i in range(n):                 # Consider current starting point        # as a subarray and update minimum        # sum and subarray indexes        curr_sum = arr[i]        if (min_sum > abs(curr_sum)):            min_sum = abs(curr_sum)            start = i            end = i         # Try all subarrays starting with i        for j in range(i + 1, n, 1):            curr_sum = curr_sum + arr[j]             # update minimum sum            # and subarray indexes            if (min_sum > abs(curr_sum)):                min_sum = abs(curr_sum)                start = i                end = j     # Return starting and ending indexes    p = [start, end]    return p # Driver Codeif __name__ == '__main__':    arr = [2, -5, 4, -6, -3]    n = len(arr)     point = findSubArray(arr, n)    print("Subarray starting from ", end = "")    print(point[0], "to", point[1]) # This code is contributed by# Surendra_Gangwar
// C# program to find subarray with// sum closest to 0using System;     class GFG{     public class Pair    {         public int first, second;        public Pair(int first, int second)        {            this.first = first;            this.second = second;        }     }         // Function to find the subarray    static Pair findSubArray(int []arr, int n)    {         int start = 0, end = 0, min_sum = int.MaxValue;         // Pick a starting point        for (int i = 0; i < n; i++)        {             // Consider current starting point            // as a subarray and update minimum            // sum and subarray indexes            int curr_sum = arr[i];            if (min_sum > Math.Abs(curr_sum))            {                min_sum = Math.Abs(curr_sum);                start = i;                end = i;            }             // Try all subarrays starting with i            for (int j = i + 1; j < n; j++)            {                curr_sum = curr_sum + arr[j];                 // update minimum sum                // and subarray indexes                if (min_sum > Math.Abs(curr_sum))                {                    min_sum = Math.Abs(curr_sum);                    start = i;                    end = j;                }            }        }         // Return starting and ending indexes        Pair p = new Pair(start, end);        return p;    }     // Drivers code    public static void Main(String[] args)    {        int []arr = {2, -5, 4, -6, -3};        int n = arr.Length;         Pair point = findSubArray(arr, n);        Console.WriteLine("Subarray starting from "                + point.first + " to " + point.second);    }} // This code is contributed by Princi Singh
<script> // JavaScript program to find subarray with// sum closest to 0 // Function to find the subarrayfunction findSubArray(arr, n) {     let start, end, min_sum = Number.MAX_SAFE_INTEGER;     // Pick a starting point    for (let i = 0; i < n; i++) {         // Consider current starting point        // as a subarray and update minimum        // sum and subarray indexes        let curr_sum = arr[i];        if (min_sum > Math.abs(curr_sum)) {            min_sum = Math.abs(curr_sum);            start = i;            end = i;        }         // Try all subarrays starting with i        for (let j = i + 1; j < n; j++) {            curr_sum = curr_sum + arr[j];             // update minimum sum            // and subarray indexes            if (min_sum > Math.abs(curr_sum)) {                min_sum = Math.abs(curr_sum);                start = i;                end = j;            }        }    }     // Return starting and ending indexes    let p = [start, end];    return p;} // Drivers code let arr = [2, -5, 4, -6, -3];let n = arr.length; let point = findSubArray(arr, n);document.write("Subarray starting from ");document.write(point[0] + " to " + point[1]); </script>
Output:  
Subarray starting from 0 to 2
Time Complexity: O(n2)An Efficient method is to perform following steps:- 
Maintain a Prefix sum array . Also maintain indexes in the prefix sum array.Sort the prefix sum array on the basis of sum.Find the two elements in a prefix sum array with minimum difference.  
Maintain a Prefix sum array . Also maintain indexes in the prefix sum array.
Sort the prefix sum array on the basis of sum.
Find the two elements in a prefix sum array with minimum difference.  
i.e.  Find min(pre_sum[i] - pre_sum[i-1]) 
Return indexes of pre_sum with minimum difference.Subarray with (lower_index+1, upper_index) will have the sum closest to 0.Taking lower_index+1 because on subtracting value at lower_index we get the sum closest to 0. That’s why lower_index need not to be included.
Return indexes of pre_sum with minimum difference.
Subarray with (lower_index+1, upper_index) will have the sum closest to 0.
Taking lower_index+1 because on subtracting value at lower_index we get the sum closest to 0. That’s why lower_index need not to be included.
C++
Java
Python3
C#
Javascript
// C++ program to find subarray with sum// closest to 0#include <bits/stdc++.h>using namespace std; struct prefix {    int sum;    int index;}; // Sort on the basis of sumbool comparison(prefix a, prefix b){    return a.sum < b.sum;} // Returns subarray with sum closest to 0.pair<int, int> findSubArray(int arr[], int n){    int start, end, min_diff = INT_MAX;     prefix pre_sum[n + 1];     // To consider the case of subarray starting    // from beginning of the array    pre_sum[0].sum = 0;    pre_sum[0].index = -1;     // Store prefix sum with index    for (int i = 1; i <= n; i++) {        pre_sum[i].sum = pre_sum[i-1].sum + arr[i-1];        pre_sum[i].index = i - 1;    }     // Sort on the basis of sum    sort(pre_sum, pre_sum + (n + 1), comparison);     // Find two consecutive elements with minimum difference    for (int i = 1; i <= n; i++) {        int diff = pre_sum[i].sum - pre_sum[i-1].sum;         // Update minimum difference        // and starting and ending indexes        if (min_diff > diff) {            min_diff = diff;            start = pre_sum[i-1].index;            end = pre_sum[i].index;        }    }     // Return starting and ending indexes    pair<int, int> p = make_pair(start + 1, end);    return p;} // Drivers codeint main(){    int arr[] = { 2, 3, -4, -1, 6 };    int n = sizeof(arr) / sizeof(arr[0]);     pair<int, int> point = findSubArray(arr, n);    cout << "Subarray starting from ";    cout << point.first << " to " << point.second;     return 0;}
// Java program to find subarray with sum// closest to 0import java.util.*; class Prefix{    int sum, index;} class Pair{    int first, second;    Pair(int a, int b)    {        first = a;        second = b;    }} class GFG{ // Returns subarray with sum closest to 0.static Pair findSubArray(int arr[], int n){    int start = -1, end = -1,     min_diff = Integer.MAX_VALUE;     Prefix pre_sum[] = new Prefix[n + 1];    for(int i = 0; i < n + 1; i++)        pre_sum[i] = new Prefix();             // To consider the case of subarray starting    // from beginning of the array    pre_sum[0].sum = 0;    pre_sum[0].index = -1;     // Store prefix sum with index    for(int i = 1; i <= n; i++)    {        pre_sum[i].sum = pre_sum[i - 1].sum +                             arr[i - 1];        pre_sum[i].index = i - 1;    }     // Sort on the basis of sum    Arrays.sort(pre_sum, ((a, b) -> a.sum - b.sum));     // Find two consecutive elements with minimum    // difference    for(int i = 1; i <= n; i++)    {        int diff = pre_sum[i].sum -                   pre_sum[i - 1].sum;         // Update minimum difference        // and starting and ending indexes        if (min_diff > diff)        {            min_diff = diff;            start = pre_sum[i - 1].index;            end = pre_sum[i].index;        }    }     // Return starting and ending indexes    Pair p = new Pair(start + 1, end);    return p;} // Driver codepublic static void main(String[] args){    int arr[] = { 2, 3, -4, -1, 6 };    int n = arr.length;     Pair point = findSubArray(arr, n);         System.out.print("Subarray starting from ");    System.out.println(point.first + " to " +                       point.second);}} // This code is contributed by jrishabh99
# Python3 program to find subarray# with sum closest to 0class prefix:         def __init__(self, sum, index):        self.sum = sum        self.index = index # Returns subarray with sum closest to 0.def findSubArray(arr, n):     start, end, min_diff = None, None, float('inf')     pre_sum = [None] * (n + 1)     # To consider the case of subarray    # starting from beginning of the array    pre_sum[0] = prefix(0, -1)     # Store prefix sum with index    for i in range(1, n + 1):        pre_sum[i] = prefix(pre_sum[i - 1].sum +                                arr[i - 1], i - 1)     # Sort on the basis of sum    pre_sum.sort(key = lambda x: x.sum)     # Find two consecutive elements    # with minimum difference    for i in range(1, n + 1):        diff = pre_sum[i].sum - pre_sum[i - 1].sum         # Update minimum difference        # and starting and ending indexes        if min_diff > diff:            min_diff = diff            start = pre_sum[i - 1].index            end = pre_sum[i].index             # Return starting and ending indexes    return (start + 1, end) # Driver codeif __name__ == "__main__":     arr = [2, 3, -4, -1, 6]    n = len(arr)     point = findSubArray(arr, n)    print("Subarray starting from",           point[0], "to", point[1]) # This code is contributed by Rituraj Jain
// C# program to find subarray with sum// closest to 0using System; class Prefix : IComparable<Prefix>{    public int sum, index;    public int CompareTo(Prefix p)         {             return this.sum-p.sum;         }} class Pair{    public int first, second;    public Pair(int a, int b)    {        first = a;        second = b;    }} public class GFG{ // Returns subarray with sum closest to 0.static Pair findSubArray(int []arr, int n){    int start = -1, end = -1,     min_diff = int.MaxValue;     Prefix []pre_sum = new Prefix[n + 1];    for(int i = 0; i < n + 1; i++)        pre_sum[i] = new Prefix();             // To consider the case of subarray starting    // from beginning of the array    pre_sum[0].sum = 0;    pre_sum[0].index = -1;     // Store prefix sum with index    for(int i = 1; i <= n; i++)    {        pre_sum[i].sum = pre_sum[i - 1].sum +                             arr[i - 1];        pre_sum[i].index = i - 1;    }     // Sort on the basis of sum    Array.Sort(pre_sum);     // Find two consecutive elements with minimum    // difference    for(int i = 1; i <= n; i++)    {        int diff = pre_sum[i].sum -                   pre_sum[i - 1].sum;         // Update minimum difference        // and starting and ending indexes        if (min_diff > diff)        {            min_diff = diff;            start = pre_sum[i - 1].index;            end = pre_sum[i].index;        }    }     // Return starting and ending indexes    Pair p = new Pair(start + 1, end);    return p;} // Driver codepublic static void Main(String[] args){    int []arr = { 2, 3, -4, -1, 6 };    int n = arr.Length;     Pair point = findSubArray(arr, n);         Console.Write("Subarray starting from ");    Console.WriteLine(point.first + " to " +                       point.second);}} // This code is contributed by 29AjayKumar
<script>// Javascript program to find subarray with sum// closest to 0class Prefix{    constructor()    {        this.sum = 0;        this.index = 0;    }} class Pair{    constructor(a, b)    {        this.first = a;        this.second = b;    }} // Returns subarray with sum closest to 0.function findSubArray(arr, n){    let start = -1, end = -1,     min_diff = Number.MAX_VALUE;       let pre_sum = new Array(n + 1);    for(let i = 0; i < n + 1; i++)        pre_sum[i] = new Prefix();               // To consider the case of subarray starting    // from beginning of the array    pre_sum[0].sum = 0;    pre_sum[0].index = -1;       // Store prefix sum with index    for(let i = 1; i <= n; i++)    {        pre_sum[i].sum = pre_sum[i - 1].sum +                             arr[i - 1];        pre_sum[i].index = i - 1;    }       // Sort on the basis of sum    pre_sum.sort(function(a, b) {return a.sum - b.sum});       // Find two consecutive elements with minimum    // difference    for(let i = 1; i <= n; i++)    {        let diff = pre_sum[i].sum -                   pre_sum[i - 1].sum;           // Update minimum difference        // and starting and ending indexes        if (min_diff > diff)        {            min_diff = diff;            start = pre_sum[i - 1].index;            end = pre_sum[i].index;        }    }       // Return starting and ending indexes    let p = new Pair(start + 1, end);    return p;} // Driver codelet arr = [2, 3, -4, -1, 6 ];let n = arr.length;let point = findSubArray(arr, n);document.write("Subarray starting from ");document.write(point.first + " to " +                   point.second); // This code is contributed by rag2127</script>
Output:  
Subarray starting from 0 to 3
Time Complexity: O(n log n)Reference: https://www.careercup.com/question?id=14583859This article is contributed by Sahil Chhabra. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
SURENDRA_GANGWAR
rituraj_jain
29AjayKumar
princi singh
jrishabh99
gfgking
rag2127
Microsoft
prefix-sum
Arrays
Sorting
Microsoft
prefix-sum
Arrays
Sorting
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Window Sliding Technique
Trapping Rain Water
Reversal algorithm for array rotation
Move all negative numbers to beginning and positive to end with constant extra space
Program to find sum of elements in a given array