Subarray with 0 Sum
Keep a running total prefix. A block arr[l..r] sums to 0 exactly when the total before l equals the total after r. So walk once, store every total in a hash set, and return true the first time a total shows up again. Put 0 in the set at the start for blocks that begin at index 0.
A zero-sum subarray ends at index i exactly when the current prefix is already in seen — the same total appeared earlier, so everything added since then sums to 0.
Problem
You are given an array of integers arr. The numbers can be positive, negative or zero.
Is there at least one contiguous, non-empty subarray whose elements add up to exactly 0?
Write bool subArrayExists(vector<int>& arr) that returns true if such a subarray exists and false otherwise.
An integer array arr of length n. Values may be negative.
true if some non-empty contiguous subarray has sum 0, otherwise false.
The subarray [2, -3, 1] (indices 1..3) adds up to 0.
The single element [0] is a subarray with sum 0.
No contiguous block of these numbers adds up to 0.
- • 1 ≤ n ≤ 10^4
- • −10^5 ≤ arr[i] ≤ 10^5
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
How many subarrays does an array of length n have? Could I check them all?
- 2.
If I keep a running total while walking from left to right, what does the total do across a block that sums to 0?
- 3.
If the running total has the same value at two different moments, what do the numbers in between add up to?
- 4.
Can a sliding window decide when to shrink if numbers can be negative?
- 5.
What about a zero-sum block that starts at the very first element?
Brute force approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Fix each start, grow the end with a running sum, stop at sum 0 | O(N²) | O(1) |
| Optimal | A zero-sum subarray exists iff some running total repeats (seed the set with 0) | O(N) | O(N) |
Why does this belong to this pattern?
- “contiguous subarray”A range [l..r] → its sum is a difference of two prefix sums.
- “sum equals exactly 0”Exact target → look up a prefix value, not a window bound.
- “numbers can be negative”A sliding window cannot decide when to shrink → use prefix sums.
- “does one exist? (true/false)”We only need to know if a prefix was seen → a hash set is enough, no counts.
This is the anchor of the Exact sum + hash map sub-pattern. The key move: "some range sums to K" becomes "some earlier prefix equals prefix − K". Here K = 0, so we look for a prefix equal to the current one, and since we only need yes/no, a set is enough. The next question (count zero-sum subarrays) keeps the same idea but needs a map of counts, and Subarray Sum Equals K then changes the lookup key to prefix − k.
Don't make this mistake
This is a pattern-confusion trap. A window drops the left element when the sum is "too big", which assumes the sum can only grow as the window grows. With negatives that is false. On [2, -1, -1] the window drops the 2 right away (sum 2 > 0), then never sees 2 − 1 − 1 = 0, and returns false.
A zero-sum block that starts at index 0 means the running total itself becomes 0. Without the starting 0 in the set there is nothing to match. [-3, 3, 5] has totals -3, 0, 5 — all different — so the code wrongly returns false.
The check is always true after inserting, so the code returns true on the first element. We must compare with earlier totals only.
The question only asks yes/no, so a set is enough. If you later need the subarray itself (or the longest one), store prefix → first index in a map instead.
Want to implement this?
Write it yourself on GeeksforGeeks, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Prefix Sum translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.