Skip to main content

โž• Prefix Sum

One-line summary: Pre-compute cumulative sums so any range query sum(L..R) is answered in O(1) after O(n) preprocessing.


๐ŸŽฏ Conceptโ€‹

A prefix sum (a.k.a. cumulative sum) pre-computes running totals so that the sum of any range can be answered in O(1) โ€” no matter how large the range.

Build a prefix sum array p where p[i] = arr[0] + arr[1] + ... + arr[i-1] (1-indexed to avoid the p[-1] edge case):

Range sum [L, R] = p[R + 1] - p[L] (with p[0] = 0)
flowchart LR
A["arr = [2, 4, 1, 3]"] --> B["p[0]=0"]
B --> C["p[1]=2"]
C --> D["p[2]=6"]
D --> E["p[3]=7"]
E --> F["p[4]=10"]
F --> G["sum(1..3) = p[4]-p[1] = 10-2 = 8"]

Difference array is the inverse: apply range updates in O(1), then read final values in O(n) via a single prefix-sum pass.

1D vs 2D Prefix Sumโ€‹

  • 1D: p[i+1] = p[i] + arr[i]. Answers sum(L..R) in O(1).
  • 2D: p[i][j] stores the sum of the rectangle from (0,0) to (i-1,j-1). Uses inclusionโ€“exclusion:
p[i][j] = arr[i-1][j-1] + p[i-1][j] + p[i][j-1] - p[i-1][j-1]

rectSum(r1,c1,r2,c2) = p[r2+1][c2+1] - p[r1][c2+1] - p[r2+1][c1] + p[r1][c1]

Diagramโ€‹

Prefix Sum Flow Prefix Sum Animation


โšก Time & Space Complexityโ€‹

OperationTimeSpaceNotes
Build 1D prefix arrayO(n)O(n)One pass
1D range queryO(1)O(1)Two lookups
Difference array updateO(1)O(n)Read values in O(n)
Build 2D prefix arrayO(mยทn)O(mยทn)Inclusionโ€“exclusion
2D rectangle queryO(1)O(1)Four lookups

Key Insight: Preprocessing pays off when you have many queries on a static array โ€” amortize O(n) build across O(1) queries.


Common Patternsโ€‹

Basic Prefix Sumโ€‹

function buildPrefix(arr) {
const p = new Array(arr.length + 1).fill(0);
for (let i = 0; i < arr.length; i++) p[i + 1] = p[i] + arr[i];
return p;
}
function rangeSum(p, l, r) {
return p[r + 1] - p[l];
}

Subarray Sum Equals K (hash map + prefix)โ€‹

function subarraySum(nums, k) {
const map = new Map([[0, 1]]);
let count = 0,
sum = 0;
for (const n of nums) {
sum += n;
count += map.get(sum - k) || 0;
map.set(sum, (map.get(sum) || 0) + 1);
}
return count;
}

2D Prefix Sum (Matrix Range Query)โ€‹

class NumMatrix {
constructor(matrix) {
const m = matrix.length,
n = matrix[0].length;
this.p = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
for (let i = 1; i <= m; i++)
for (let j = 1; j <= n; j++)
this.p[i][j] =
matrix[i - 1][j - 1] + this.p[i - 1][j] + this.p[i][j - 1] - this.p[i - 1][j - 1];
}
sumRegion(r1, c1, r2, c2) {
return this.p[r2 + 1][c2 + 1] - this.p[r1][c2 + 1] - this.p[r2 + 1][c1] + this.p[r1][c1];
}
}
// Build: O(m*n), Query: O(1)

๐Ÿงช Worked Example: Pivot Indexโ€‹

Find the index where the sum of elements to the left equals the sum to the right.

function pivotIndex(nums) {
const total = nums.reduce((s, x) => s + x, 0);
let leftSum = 0;
for (let i = 0; i < nums.length; i++) {
// right sum = total - leftSum - nums[i]
if (leftSum === total - leftSum - nums[i]) return i;
leftSum += nums[i];
}
return -1;
}
// A running prefix (leftSum) lets us check the balance point in one pass.
// Time: O(n), Space: O(1)

Pitfallsโ€‹

  • Off-by-one: use 1-indexed prefix array to avoid p[-1] issues
  • 2D prefix sum: remember the inclusion-exclusion formula

Practice Problemsโ€‹

ProblemDifficultySolution
LC 1480 โ€” Running Sum of 1D ArrayEasy
LC 303 โ€” Range Sum QueryEasy
LC 560 โ€” Subarray Sum Equals KMedium
LC 525 โ€” Contiguous ArrayMedium
LC 304 โ€” Range Sum Query 2DMedium
LC 1171 โ€” Remove Zero Sum Consecutive NodesMedium
CC โ€” Sumtastic (SUMTASTIC)Medium
CC โ€” Chef Segment (CHSEG)Medium
LC 363 โ€” Max Sum of Rectangle No Larger Than KHard
LC 930 โ€” Binary Subarrays With SumMedium
LC 523 โ€” Continuous Subarray SumMedium
LC 238 โ€” Product of Array Except SelfMedium
LC 724 โ€” Find Pivot IndexEasy
LC 1031 โ€” Maximum Sum of Two Non-Overlapping SubarraysMedium
LC 1094 โ€” Car PoolingMedium
LC 1109 โ€” Corporate Flight BookingsMedium
LC 1248 โ€” Count Number of Nice SubarraysMedium
LC 1314 โ€” Matrix Block SumMedium
LC 1442 โ€” Count Triplets That Can Form Two Arrays of Equal XORMedium
LC 1590 โ€” Make Sum Divisible by PMedium
LC 1658 โ€” Minimum Operations to Reduce X to ZeroMedium
LC 1664 โ€” Ways to Make a Fair ArrayMedium
LC 1732 โ€” Find the Highest AltitudeEasy
LC 1991 โ€” Find the Middle Index in ArrayEasy
CC โ€” Range Sum Queries (RANGESUM)Easy
CC โ€” Prefix Sum Array (PREFSUM)Easy
CC โ€” Subarray Queries (SUBARR)Medium

โ† Back to Home ยท ยฉ sparshjaswal