Imagine you’re a cashier and need to tell customers their subtotal at any point during shopping. Instead of adding items from scratch each time, you keep a running total. That’s prefix sum—precompute cumulative sums so range queries become O(1).
Pattern Recognition Signal: Whenever you see “sum of elements from index L to R” or “multiple range queries on static array”, think Prefix Sum.
Original: [3, 1, 4, 1, 5, 9, 2, 6]Prefix: [0, 3, 4, 8, 9, 14, 23, 25, 31] ^-- We add a 0 at the start for easier math
Key Insight: sum(L, R) = prefix[R+1] - prefix[L]Why? Because prefix[R+1] contains sum of elements 0 to R, and prefix[L] contains sum of elements 0 to L-1. Subtracting gives us exactly L to R.
Problem: Count subarrays with sum equal to K.Identification Signals:
“Count subarrays” or “find subarray”
“Sum equals K”
Constraints allow O(n) solution
The Insight: If prefix[j] - prefix[i] = K, then subarray (i, j] has sum K. Rearranging: prefix[i] = prefix[j] - K. Use a hashmap to count prefix sums seen so far.
Copy
int subarraySum(vector<int>& nums, int k) { unordered_map<long long, int> prefixCount; prefixCount[0] = 1; // Empty prefix has sum 0 long long currentSum = 0; int count = 0; for (int num : nums) { currentSum += num; // How many prefixes have sum = currentSum - k? if (prefixCount.count(currentSum - k)) { count += prefixCount[currentSum - k]; } prefixCount[currentSum]++; } return count;}
Problem: Answer multiple rectangle sum queries on a 2D grid.The Insight: Build a 2D prefix sum where prefix[i][j] = sum of all elements in the rectangle from (0,0) to (i-1, j-1).
Copy
// Build 2D prefix sumvector<vector<long long>> build2DPrefix(const vector<vector<int>>& grid) { int n = grid.size(), m = grid[0].size(); vector<vector<long long>> prefix(n + 1, vector<long long>(m + 1, 0)); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { prefix[i][j] = grid[i-1][j-1] + prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1]; } } return prefix;}// Query sum of rectangle from (r1,c1) to (r2,c2) inclusivelong long rectSum(const vector<vector<long long>>& prefix, int r1, int c1, int r2, int c2) { return prefix[r2+1][c2+1] - prefix[r1][c2+1] - prefix[r2+1][c1] + prefix[r1][c1];}
Visual: To get the sum of the green rectangle, we use inclusion-exclusion:
Copy
+---+---+---+| A | B | |+---+---+---+| C | G | | G = Total - A - B - C + overlap+---+---+---+