Searching & SortingProblem 15 of 36
Print all subarrays with 0 sum
Problem Statement
Given an array of integers, print all subarrays with 0 sum. A subarray is a contiguous part of the array.
Constraints:
- Array can contain positive, negative, and zero values
- Print/return all subarrays, not just count
Example:
- Input:
arr = [6, 3, -1, -3, 4, -2, 2, 4, 6, -12, -7] - Output:
- Subarray from index 2 to 4 ([-1, -3, 4])
- Subarray from index 2 to 6 ([-1, -3, 4, -2, 2])
- Subarray from index 5 to 6 ([-2, 2])
- Subarray from index 6 to 9 ([2, 4, 6, -12])
- Subarray from index 0 to 10 (entire array)
Approach 1: Brute Force (Check All Subarrays)
Intuition
Generate all possible subarrays and check if their sum equals zero.
Algorithm
- For each starting index i
- For each ending index j >= i
- Calculate sum of subarray [i, j]
- If sum is 0, add to result
java
import java.util.*;
public class Solution {
public List<int[]> findZeroSumSubarrays(int[] arr) {
List<int[]> result = new ArrayList<>();
int n = arr.length;
for (int i = 0; i < n; i++) {
int sum = 0;
for (int j = i; j < n; j++) {
sum += arr[j];
if (sum == 0) {
result.add(new int[]{i, j});
}
}
}
return result;
}
}Complexity Analysis
- Time Complexity: O(n²) - Nested loops (with O(n³) if sum calculated freshly)
- Space Complexity: O(k) - Where k is number of zero-sum subarrays
Approach 2: Using Prefix Sum and HashMap (Optimal)
Intuition
If prefix sum at index j equals prefix sum at index i, then subarray (i+1, j) has sum 0. Use a hashmap to store all indices where each prefix sum occurs.
Key Insight
prefixSum[j] - prefixSum[i] = sum of subarray (i+1, j)
If prefixSum[j] == prefixSum[i], then subarray (i+1, j) has sum 0
Also, if prefixSum[i] == 0, then subarray (0, i) has sum 0.
Algorithm
- Calculate running prefix sum
- Use hashmap: prefix_sum -> list of indices where this sum occurred
- If prefix_sum is 0, subarray from start to current index has sum 0
- If prefix_sum seen before, we have zero-sum subarrays ending at current index
java
import java.util.*;
public class Solution {
public List<int[]> findZeroSumSubarrays(int[] arr) {
List<int[]> result = new ArrayList<>();
int n = arr.length;
// Map: prefix_sum -> list of indices
Map<Integer, List<Integer>> prefixSumIndices = new HashMap<>();
int prefixSum = 0;
for (int i = 0; i < n; i++) {
prefixSum += arr[i];
// Subarray starting from index 0
if (prefixSum == 0) {
result.add(new int[]{0, i});
}
// Check if this prefix sum was seen before
if (prefixSumIndices.containsKey(prefixSum)) {
for (int prevIdx : prefixSumIndices.get(prefixSum)) {
result.add(new int[]{prevIdx + 1, i});
}
}
// Store current index for this prefix sum
prefixSumIndices.computeIfAbsent(prefixSum, k -> new ArrayList<>()).add(i);
}
return result;
}
}Dry Run Example
arr = [6, 3, -1, -3, 4, -2, 2, 4, 6, -12, -7]
i=0: prefixSum=6
Map: {6: [0]}
i=1: prefixSum=9
Map: {6: [0], 9: [1]}
i=2: prefixSum=8
Map: {6: [0], 9: [1], 8: [2]}
i=3: prefixSum=5
Map: {6: [0], 9: [1], 8: [2], 5: [3]}
i=4: prefixSum=9
9 seen at [1], add (2, 4)
Map: {6: [0], 9: [1, 4], 8: [2], 5: [3]}
i=5: prefixSum=7
Map: {..., 7: [5]}
i=6: prefixSum=9
9 seen at [1, 4], add (2, 6), (5, 6)
Map: {..., 9: [1, 4, 6]}
i=7: prefixSum=13
Map: {..., 13: [7]}
i=8: prefixSum=19
Map: {..., 19: [8]}
i=9: prefixSum=7
7 seen at [5], add (6, 9)
Map: {..., 7: [5, 9]}
i=10: prefixSum=0
prefixSum==0, add (0, 10)
Map: {..., 0: [10]}
Result: [(2,4), (2,6), (5,6), (6,9), (0,10)]
Complexity Analysis
- Time Complexity: O(n + k) where k is number of subarrays
- Space Complexity: O(n) - HashMap storage
Just Count Zero-Sum Subarrays
Variation: Find Longest Zero-Sum Subarray
Key Takeaways
- Prefix Sum Property: If prefix sums at indices i and j are equal, sum of subarray (i+1, j) is 0
- HashMap Storage: Store all indices for each prefix sum to find all subarrays
- Count vs Print: Storing counts is simpler; storing indices needed to print subarrays
- Zero Prefix Sum: Don't forget subarrays starting from index 0
- Time Complexity: O(n) for counting, O(n + k) for printing all k subarrays
- Applications: Finding balanced parentheses, equal 0s and 1s subarrays