Prefix Sum: Complete Guide with Range Query Examples
Prefix sum is the pattern you reach for when a problem keeps asking about sums of ranges. Sum from index 2 to index 5. Sum from index 0 to index 3. Sum of the whole array. Answering each request by adding elements one by one costs
Definition: build an array where prefix[i] holds the sum of the first i elements of the input. The sum of nums[left..right] is then prefix[right + 1] - prefix[left], which is one subtraction no matter how long the range is.
Real-World Analogy
You keep a spreadsheet of monthly spending with a running total column. By December, the last row shows what you spent all year. Someone asks what you spent from March through July. You do not reopen the receipts. You read the July running total, subtract the February running total, and the difference is exactly the five-month sum. The running total column is the prefix array. The one subtraction is the range query. As long as the numbers do not change, that single column answers every month-range question for the rest of the year.
Visual Explanation
Building the prefix array is one pass that carries the running total forward. Each new slot in prefix takes the previous total and adds the next input element.
graph TD
P0["prefix[0] = 0"]
P1["prefix[1] = prefix[0] + nums[0] = 0 + 3 = 3"]
P2["prefix[2] = prefix[1] + nums[1] = 3 + 1 = 4"]
P3["prefix[3] = prefix[2] + nums[2] = 4 + 4 = 8"]
P4["prefix[4] = prefix[3] + nums[3] = 8 + 2 = 10"]
P5["prefix[5] = prefix[4] + nums[4] = 10 + 5 = 15"]
P0 --> P1 --> P2 --> P3 --> P4 --> P5
Q["Query: sum nums[2..4] = prefix[5] - prefix[2] = 15 - 4 = 11"]
P5 -.-> Q
Two details matter here. The leading 0 is not filler. It makes prefix[0] a valid subtraction for queries that start at index 0, so those queries need no special handling. And in the query step, prefix[5] already contains the sum of the first five elements, nums[0..4]. Subtracting prefix[2], the sum of nums[0..1], removes everything before the range and leaves exactly nums[2..4].
The same idea scales to grids. A 2D prefix array stores the sum of every submatrix anchored at the top-left corner, and a submatrix sum becomes a four-corner combination over the prefix array instead of a summed loop. There is also a sibling technique called the difference array. It reverses the problem. Instead of answering many range queries on a static array, it applies many range additions to a large array at
When to Use Prefix Sum
These are the problem shapes where prefix sums earn their keep.
- The input array is static and you need many range-sum queries. Onebuild pays for itself withO(N)queries, which is exactly the profile of Range Sum Query Immutable.O(1)
- The question asks whether some subarray sums to
k, or how many subarrays sum tok. Those reduce to comparing prefix sums, usually by storing what prefix values you have already seen in a hash table. - The numbers can be negative. A sliding window still works when sums only grow, but it breaks once values can go down. Prefix sums handle negative numbers without a special case, because they only ever add.
- The input is a matrix and the question is about submatrix sums. A 2D prefix array is the grid version of the same trick.
- You have a large collection of range updates with known bounds. Difference arrays process the whole range-update class intime per update.O(1)
If the array changes often between queries, prefix sums go stale and you should look for a segment tree or a binary indexed tree instead.
Complexity Analysis
Two numbers define this pattern: the cost to build the prefix array once, and the cost of each query after that.
| Operation | Time | Space | Explanation |
|---|---|---|---|
| Build 1D prefix array | O(N) | O(N) | One pass, one running total, N+1 stored values |
| Single range sum query | O(1) | O(1) | Two array reads, one subtraction |
| Build 2D prefix array | O(M*N) | O(M*N) | Every cell visited once during the build |
| 2D submatrix query | O(1) | O(1) | Four corner reads, inclusion-exclusion |
| Prefix sums plus hashmap | O(N) | O(N) | One pass plus a map of prior prefix values |
The build is
Common Mistakes
These are the bugs that look right in the room and fail on a hidden case.
Off-by-one in the gap index. The query is prefix[right + 1] - prefix[left]. Because prefix[i] is the sum of the first i elements, a range ending at right needs the prefix that includes right, which is prefix[right + 1]. Writing prefix[right] - prefix[left] returns the sum of nums[left..right-1] and drops the last element. To catch this, test a one-element range. The query [2, 2] must return nums[2], and prefix[3] - prefix[2] is the only pair that does.
Building against the wrong source index. In the build loop, prefix[i] draws from nums[i - 1], not nums[i]. Mixing these shifts the whole array by one and the math above breaks completely. Catch it by checking that prefix[1] equals nums[0] on the same input, and that a full-range query equals the whole sum you can compute by hand.
Forgetting the {0: 1} seed in counting problems. When you count subarrays that sum to k with a hashmap, the map must start with the empty prefix set to one. Otherwise every valid subarray that begins at index 0 is never counted, and the answer is short by exactly those cases. The clue that something is wrong is a solution that passes the test with an empty array but fails the first example with a positive answer.
Ignoring overflow. Cumulative sums grow. With large inputs or large values, an int can wrap into negative territory and silently poison every query. In Java use long instead, in C++ use long long, and in Go use int64. If the language you write in has an unbounded integer, no change is needed.
Related Patterns
- Hash Table . Subarray Sum Equals K and its relatives are prefix sums plus a counting hashmap. The hash table page covers the counting mechanics that do the real work.
- Sliding Window
. When all values are non-negative, a sliding window answers subarray-sum questions intime andO(N)space. When negative numbers appear, sliding windows stop being valid and prefix sums take over.O(1)
- Kadane’s Algorithm
. Kadane finds the single best subarray intime with no extra memory. Prefix sums answer whole batches of range queries. Use the one that matches the shape of the question.O(N)
Next Steps
Once the concept is clear, turn it into code you can produce without thinking. The code templates give you the range-query class, the counting variant, and the difference array in six languages. Then work through the practice problems to see the pattern holding up against real interview questions.