Open In App

Longest Subarray with 0 Sum

Last Updated : 03 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] consisting of both positive and negative integers, the objective is to find the length of the longest subarray whose elements sum is zero.
A subarray is a contiguous part of an array, formed by selecting one or more consecutive elements while maintaining their original order.

Examples:

Input: arr[] = [15, -2, 2, -8, 1, 7, 10]
Output: 5
Explanation: The longest subarray with sum equals to 0 is [-2, 2, -8, 1, 7].

Input: arr[] = [1, 2, 3]
Output: 0
Explanation: There is no subarray with 0 sum.

Input:  arr[] = [1, 0, 3]
Output:  1
Explanation: The longest sub-array with sum equal to 0 is [0].

[Naive Approach] Iterating over all subarrays - O(n2) Time and O(1) Space

We try all possible subarrays using two nested loops. For each subarray, we calculate its sum, and if the sum is zero, we update the maximum length accordingly.

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int maxLength(vector<int>& arr) {  
    int n = arr.size();
    int maxLen = 0; 

    // Loop through each starting point
    for (int i = 0; i < n; i++) {
        int currSum = 0;

        // Try all subarrays starting from 'i'
        for (int j = i; j < n; j++) {
            currSum += arr[j]; 

            // as currSum becomes 0, update maxLen
            if (currSum == 0)
                maxLen = max(maxLen, j - i + 1);
        }
    }
    return maxLen;
}

int main() {
    vector<int> arr = {15, -2, 2, -8, 1, 7, 10};
    cout << maxLength(arr) << endl;
    return 0;
}
C
#include <stdio.h>

int maxLength(int arr[], int n) {
    int maxLen = 0;

    // Loop through each starting point
    for (int i = 0; i < n; i++) {
        int currSum = 0;

        // Try all subarrays starting from 'i'
        for (int j = i; j < n; j++) {
            currSum += arr[j];

            // If currSum becomes 0, update maxLen if required
            if (currSum == 0) {
                int length = j - i + 1;
                if (length > maxLen)
                    maxLen = length;
            }
        }
    }

    return maxLen;
}

int main() {
    int arr[] = {15, -2, 2, -8, 1, 7, 10};
    int size = sizeof(arr) / sizeof(arr[0]);

    printf("%d\n", maxLength(arr, size));
    return 0;
}
Java
class GfG {
  
    static int maxLength(int arr[]) {
        
        int n = arr.length;
        
        int maxLen = 0;

        // Loop through each starting point
        for (int i = 0; i < n; i++) {
          
            int currSum = 0;

            // Try all subarrays starting from 'i'
            for (int j = i; j < n; j++) {
              
                // Add the current element to currSum
                currSum += arr[j];
                
                // as the currSum is 0, update the maxLen
                if (currSum == 0)
                    maxLen = Math.max(maxLen, j - i + 1);
            }
        }
        return maxLen;
    }

    public static void main(String[] args) {
        int arr[] = {15, -2, 2, -8, 1, 7, 10};
        System.out.println(maxLength(arr));
    }
}
Python
def maxLength(arr):
    n = len(arr)
    maxLen = 0

    # Loop through each starting point
    for i in range(n):
        currSum = 0

        # Trying  all subarrays starting from 'i'
        for j in range(i, n):
            currSum += arr[j]

            # as currSum becomes 0, update maxLen
            if currSum == 0:
                maxLen = max(maxLen, j - i + 1)

    return maxLen


if __name__ == "__main__":
    arr = [15, -2, 2, -8, 1, 7, 10]
    print(maxLength(arr))
C#
using System;
using System.Collections.Generic;

class GfG {
    static int maxLength(List<int> arr) {
        int n = arr.Count;
        int maxLen = 0;

        // Loop through each starting point
        for (int i = 0; i < n; i++) {
            int currSum = 0;

            // Try all subarrays starting from 'i'
            for (int j = i; j < n; j++) {
                currSum += arr[j];

                // as currSum becomes 0, update maxLen
                if (currSum == 0)
                    maxLen = Math.Max(maxLen, j - i + 1);
            }
        }

        return maxLen;
    }

    static void Main() {
        List<int> arr = new List<int> { 15, -2, 2, -8, 1, 7, 10};
        Console.WriteLine(maxLength(arr));
    }
}
JavaScript
function maxLength(arr) {
    let n = arr.length;
    let maxLen = 0;

    // Loop through each starting point
    for (let i = 0; i < n; i++) {
        let currSum = 0;

        // Try all subarrays starting from 'i'
        for (let j = i; j < n; j++) {
            currSum += arr[j];

            // as currSum becomes 0, update maxLen
            if (currSum === 0) {
                maxLen = Math.max(maxLen, j - i + 1);
            }
        }
    }

    return maxLen;
}


// Driver Code
let arr = [15, -2, 2, -8, 1, 7, 10];
console.log(maxLength(arr));

Output
5

[Expected Approach] Using Hashmap and Prefix Sum - O(n) Time and O(n) Space

The idea is based on the observation that for two different indices i and j (where j > i) if the prefix sums Si and Sj are equal, it means that the sum of the elements between indices i+1 and j is zero. This is because:

  • Sj - Si = arr[i+1] + arr[i+2] + …... + arr[j]
  • If Si = Sj, then: arr[i+1] + arr[i+2] + …... + arr[j] = 0. [ The subarray sum from i+1 to j is 0. ]

Step-by-step approach:

  • Initialize a variable prefixSum = 0 and a hashmap firstSeen = {}.
  • Insert 0 into the hashmap with index -1.
    This handles the case where a subarray starting from index 0 itself has a sum of zero.
  • Traverse the array element by element:
    • Update the running prefix sum.
    • If this prefix sum has not been seen before, store its index in the hashmap.
    • If this prefix sum has been seen before, it means the elements between the previous index (where this sum was first seen) and the current index sum to zero.
    • Update the maximum length accordingly.

Working:

C++
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

int maxLength(vector<int>& arr) {
    int n = arr.size();
    
    // prefixSum -> first index
    unordered_map<int, int> firstSeen; 
    int prefixSum = 0;
    int maxLen = 0;

    // insert prefix sum 0 at index -1
    // to handle sum from start
    firstSeen[0] = -1;

    for (int i = 0; i < n; i++) {
        prefixSum += arr[i];

        // prefix sum has been seen before
        if (firstSeen.find(prefixSum) != firstSeen.end()) {
            int prevIndex = firstSeen[prefixSum];
            int length = i - prevIndex;
            maxLen = max(maxLen, length);
        }
        else {
            
            // Store first occurrence of this prefix sum
            firstSeen[prefixSum] = i;
        }
    }

    return maxLen;
}

int main() {
    vector<int> arr = {15, -2, 2, -8, 1, 7, 10};
    cout << maxLength(arr) << endl;
    return 0;
}
Java
import java.util.HashMap;
import java.util.Map;

class GfG {
    public static int maxLength(int[] arr) {
        int n = arr.length;

        // prefixSum -> first index
        Map<Integer, Integer> firstSeen = new HashMap<>();
        int prefixSum = 0;
        int maxLen = 0;

        // insert prefix sum 0 at index -1
        // to handle sum from start
        firstSeen.put(0, -1);

        for (int i = 0; i < n; i++) {
            prefixSum += arr[i];

            // prefix sum has been seen before
            if (firstSeen.containsKey(prefixSum)) {
                int prevIndex = firstSeen.get(prefixSum);
                int length = i - prevIndex;
                maxLen = Math.max(maxLen, length);
            } else {
                
                // Store first occurrence of this prefix sum
                firstSeen.put(prefixSum, i);
            }
        }

        return maxLen;
    }

    public static void main(String[] args) {
        int[] arr = {15, -2, 2, -8, 1, 7, 10};
        System.out.println(maxLength(arr));
    }
}
Python
def maxLength(arr):
    n = len(arr)

    # prefixSum -> first index
    firstSeen = {}
    prefixSum = 0
    maxLen = 0

    # insert prefix sum 0 at index -1
    # to handle sum from start
    firstSeen[0] = -1

    for i in range(n):
        prefixSum += arr[i]

        # prefix sum has been seen before
        if prefixSum in firstSeen:
            prevIndex = firstSeen[prefixSum]
            length = i - prevIndex
            maxLen = max(maxLen, length)
        else:
            # Store first occurrence of this prefix sum
            firstSeen[prefixSum] = i

    return maxLen

if __name__ == "__main__":
    arr = [15, -2, 2, -8, 1, 7, 10]
    print(maxLength(arr))
C#
using System;
using System.Collections.Generic;

class GfG {
    public static int maxLength(List<int> arr) {
        int n = arr.Count;

        // prefixSum -> first index
        Dictionary<int, int> firstSeen = 
                            new Dictionary<int, int>();
        int prefixSum = 0;
        int maxLen = 0;

        // insert prefix sum 0 at index -1
        // to handle sum from start
        firstSeen[0] = -1;

        for (int i = 0; i < n; i++) {
            prefixSum += arr[i];

            // prefix sum has been seen before
            if (firstSeen.ContainsKey(prefixSum)) {
                int prevIndex = firstSeen[prefixSum];
                int length = i - prevIndex;
                maxLen = Math.Max(maxLen, length);
            } else {
                
                // Store first occurrence of this prefix sum
                firstSeen[prefixSum] = i;
            }
        }

        return maxLen;
    }

    static void Main() {
        List<int> arr = new List<int> {15, -2, 2, -8, 1, 7, 10};
        Console.WriteLine(maxLength(arr));
    }
}
JavaScript
function maxLength(arr) {
    let n = arr.length;

    // prefixSum -> first index
    let firstSeen = new Map();
    let prefixSum = 0;
    let maxLen = 0;

    // insert prefix sum 0 at index -1 
    // to handle sum from start
    firstSeen.set(0, -1);

    for (let i = 0; i < n; i++) {
        prefixSum += arr[i];

        // prefix sum has been seen before
        if (firstSeen.has(prefixSum)) {
            let prevIndex = firstSeen.get(prefixSum);
            let length = i - prevIndex;
            maxLen = Math.max(maxLen, length);
        } else {
            
            // Store first occurrence of this prefix sum
            firstSeen.set(prefixSum, i);
        }
    }

    return maxLen;
}


//  Driver Code 
const arr = [15, -2, 2, -8, 1, 7, 10];
console.log(maxLength(arr));

Output
5

Related Articles:


Next Article

Similar Reads