Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
An equilibrium index is a position where the sum of elements to its left equals the sum to its right. Compute the total sum once, then sweep left to right maintaining a running left sum; at each i, the right sum is total − leftSum − nums[i]. When leftSum == rightSum, return i. O(n) time, O(1) space.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you avoid the O(n²) recompute-the-suffix trap and instead carry a running prefix, getting the right sum in O(1) from the precomputed total.
Where candidates slip
Including nums[i] in the left side, recomputing the right sum with an inner loop (O(n²)), or overflowing a 32-bit total.
How to stand out
State rightSum = total − leftSum − nums[i] cleanly, note the boundary indices (empty side = 0), and mention you'd return all equilibrium indices if asked rather than just the first.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachFirst decision previewFind equilibrium indexRecompute right sum each step?YesNoExplore the full treeCollapse the tree
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
Recompute Right Sum Each Step (Baseline)
1Hint 1Explore hintHide hint
For each candidate index i, you need the sum of everything left of i and everything right of i. What's the most direct way to get those?
2Hint 2Explore hintHide hint
For each i, run one loop summing nums[0..i-1] and another summing nums[i+1..n-1], then compare.
3Hint 3Explore hintHide hint
That re-sums overlapping ranges every iteration — O(n²). What did you compute on the previous step that you could reuse?
A · Core idea
For every index i, compute the left sum and right sum from scratch by scanning the two sides, then check if they're equal.
Why it's the obvious first cut. It maps directly to the definition: 'sum of the left equals sum of the right'. No cleverness, just two inner sums per candidate. It's a fine way to confirm you understand the problem and produces a correct oracle.
Why it's wasteful. Each step re-sums nearly the whole array, even though consecutive indices share almost all of their left and right ranges. The left sum at index i is just the left sum at i−1 plus nums[i−1] — recomputing it from zero throws that away. That redundancy is the quadratic cost.
The reuse that points to the fix. Notice the left sum only grows by one element as i advances. Carrying it in a single accumulator removes the inner left loop entirely. And since left + nums[i] + right == total, the right sum is just total − left − nums[i] — no inner right loop either. Two observations collapse O(n²) to O(n).
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
nums = [1, 2, 3]Array state
i=1
left = 1, right = 3
-1C · Code with teaching comments
Reference implementation previewpublic int equilibriumIndex(int[] nums) { int n = nums.length; for (int i = 0; i < n; i++) { long left = 0, right = 0; for (int l = 0; l < i; l++) left += nums[l];Explore the full codeHide the full code
D · Why it works and complexityO(n²) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The naive version recomputes overlapping ranges. Spotting that the left sum changes by exactly one element per step is the cue to maintain it incrementally instead of rebuilding it.
ComplexityO(n²) time, O(1) space — For each of n indices you sum up to n other elements → O(n²). Constant extra space.
E · Edge cases and pitfalls3Re-summing overlapping ranges — O(n²) for n = 10⁵.Explore edge casesHide edge cases
Pitfalls
- Re-summing overlapping ranges — O(n²) for n = 10⁵.
- Accidentally including nums[i] in one of the sides.
- Using int for the partial sums and overflowing.
Approach 2 of 2 · Optimal
Total Minus Running Prefix (Optimal)
1Hint 1Explore hintHide hint
What single quantity, computed once up front, lets you avoid ever summing the right side directly?
2Hint 2Explore hintHide hint
The grand total. Since left + nums[i] + right = total, you get right = total − left − nums[i] in O(1).
3Hint 3Explore hintHide hint
Sweep i from 0, keep leftSum, check leftSum == total − leftSum − nums[i], then add nums[i] to leftSum AFTER the check.
A · Core idea
Compute the grand total once. Then sweep left to right with a running leftSum. At each index the right sum is whatever's left over: total − leftSum − nums[i]. Compare; if equal, you've found an equilibrium index.
Why the right sum is free. The array splits at i into three disjoint parts: everything left, the element nums[i], and everything right. Their sums obey leftSum + nums[i] + rightSum = total. Rearranging gives rightSum = total − leftSum − nums[i] — a single subtraction, no loop. Precomputing total once is what makes every per-index right sum O(1).
Why the update order is critical. You must check equality before folding nums[i] into leftSum. The definition excludes the pivot from the left side, so at the moment of the check leftSum must hold only nums[0..i-1]. Add nums[i] first and the current element contaminates the left sum, shifting every comparison and producing wrong answers. Update after the check.
Why boundaries just work. At i = 0, leftSum is still 0 (the empty left side), and rightSum = total − 0 − nums[0] is the sum of everything after — exactly right. At i = n−1, rightSum computes to 0. Empty sides legitimately sum to 0, so no special-casing is needed.
Why a long total. With up to 10⁵ elements of magnitude up to 10⁴, the total can reach 10⁹, comfortably within 32 bits here — but if values were up to 10⁹ it would overflow. Defaulting to long for the accumulator is the safe habit and costs nothing.
Why negatives don't break it. The method never assumes the prefix sum increases, so negative numbers and zeros are handled with no extra logic — unlike approaches that try to stop early on a sign change.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
nums = [-7, 1, 5, 2, -4, 3, 0]Array state
i=3
left = -1, right = -1 → match
3C · Code with teaching comments
D · Why it works and complexityO(n) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
You never need to sum the right side explicitly — it's the complement of the left within the fixed total. 'Derive one side from the whole minus the other' is the prefix-sum move that also powers pivot index, partition, and subarray-sum problems.
ComplexityO(n) time, O(1) space — One pass to compute the total, one pass to scan with a running left sum — two linear passes, O(n). Only a couple of accumulators, so O(1) extra space.
E · Edge cases and pitfalls6nums = [5] — i=0: left=0, right=total−0−5=0 → match, return 0. Both sides empty.Explore edge casesHide edge cases
Edge cases handled
nums = [5]i=0: left=0, right=total−0−5=0 → match, return 0. Both sides empty.nums = []Loop never runs; returns -1. No index exists.nums = [0, 0, 0]i=0 already balances (0 == 0); returns the leftmost, 0.
Pitfalls
- Adding nums[i] to leftSum before the check — pivot leaks into the left side.
- Recomputing rightSum with a loop instead of the subtraction.
- Overflowing the total with a 32-bit accumulator for large values.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic int equilibriumIndex(int[] nums) { long total = 0; for (int x : nums) { total += x; }Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Updating leftSum before the check
The pivot must be excluded from the left side. Adding nums[i] first means leftSum already includes the pivot, so every comparison is wrong.
Explore the code comparisonHide the code comparison
Updating leftSum before the check
The pivot must be excluded from the left side. Adding nums[i] first means leftSum already includes the pivot, so every comparison is wrong.
Don't write this
for i, x in enumerate(nums):
left_sum += x # pivot leaks in
right_sum = total - left_sum
if left_sum == right_sum:
return iWrite this instead
for i, x in enumerate(nums):
right_sum = total - left_sum - x
if left_sum == right_sum:
return i
left_sum += x # update after the check2Recomputing the suffix in a loop
Summing the right side from scratch per index is O(n²). Derive it as total − leftSum − nums[i] instead.
Explore the code comparisonHide the code comparison
Recomputing the suffix in a loop
Summing the right side from scratch per index is O(n²). Derive it as total − leftSum − nums[i] instead.
Don't write this
for (int r = i + 1; r < n; r++) right += nums[r]; // O(n) per indexWrite this instead
long rightSum = total - leftSum - nums[i]; // O(1) per index332-bit total overflow
10⁵ values of magnitude up to 10⁹ overflow an int total, corrupting every comparison.
Explore the code comparisonHide the code comparison
32-bit total overflow
10⁵ values of magnitude up to 10⁹ overflow an int total, corrupting every comparison.
Don't write this
int total = 0;
for (int x : nums) total += x; // can overflowWrite this instead
long total = 0;
for (int x : nums) total += x;Revise
Carry the pattern into the interview
Pattern to remember
Total sum minus running prefix — derive the right sum in O(1)
Code pattern to memorize
total = sum(nums)
leftSum = 0
for i, x in enumerate(nums):
rightSum = total - leftSum - x
if leftSum == rightSum: return i
leftSum += x
return -1Rules to remember
- 1The element at
iitself belongs to neither side: rightSum = total − leftSum − nums[i]. - 2Add
nums[i]toleftSumafter the equality check, not before — otherwise the current element leaks into the left side. - 3Boundary indices count: at
i = 0the left sum is0; ati = n−1the right sum is0. An empty side sums to 0, which is valid. - 4Use a 64-bit
longfor the total — summing 10⁵ values up to 10⁹ exceeds 32-bit range. - 5Negative numbers and zeros are fine; don't assume the prefix sum is monotonic.
Use this pattern when
- Finding a split point where two sides of an array balance by sum
- Pivot-index / 'middle of the array' problems
- Any single-pass question reducible to 'left aggregate vs right aggregate'
- When you'd otherwise recompute a suffix sum inside a loop — replace it with total − prefix
Choose another pattern when
- You need balance by count or product, not sum → adapt the aggregate, same skeleton
- Many queries over changing arrays → a Fenwick/segment tree, not a one-pass scan
- 2D / matrix balance → prefix-sum grid, different bookkeeping
Interview takeaway
Equilibrium index is the cleanest demonstration of the prefix-sum trick: precompute the total, carry a running left sum, and get the right sum for free as total − left − current. That 'derive one side from the whole' move recurs across pivot, balance, and partition problems.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternPrefix-sum with total-minus-prefix derivation. The transferable move is computing the total once and reading any suffix aggregate as the complement of the running prefix — the backbone of pivot-index, partition, and range-balance problems.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Find Pivot Index (LeetCode 724)Identical problem under a different name — leftmost index where left sum equals right sum.
- Product of Array Except SelfSame prefix/suffix decomposition, but with products and returning an array of results.
- Maximum Subarray (Kadane)Another running-aggregate single pass — carry a running best instead of a running sum.