We're given a 2D grid of integers and need to answer rectangle sum queries efficiently. Each query hands us the top-left and bottom-right corners of a rectangle, and we need to return the sum of all elements inside it.
A single query is easy: loop through the rectangle and add everything up. The difficulty is that sumRegion can be called up to 10,000 times, and the problem requires O(1) per query. That rules out re-scanning the rectangle each time and forces us to do preprocessing during construction that lets any later query resolve in constant time.
The 1D version of this problem (Range Sum Query - Immutable) is solved with a prefix sum array, where one subtraction gives the sum of any subarray in O(1). The question is whether that idea extends to two dimensions.
1 <= m, n <= 200 and at most 10^4 calls → A 200x200 matrix scanned per query across 10^4 queries is 4 10^8 cell reads in the worst case, and the problem requires O(1) per query regardless. Both point to the same target: O(m n) preprocessing, O(1) per query.-10^4 <= matrix[i][j] <= 10^4 → Values can be negative, so any approach must handle subtraction and cannot assume sums only grow. The largest possible rectangle sum is 200 200 10^4 = 4 * 10^8, which fits in a 32-bit signed int, so int is safe for the accumulators.Do exactly what the problem describes: for each query, iterate through every cell in the rectangle and add up the values. The constructor stores the matrix and does no preprocessing.
This is correct but slow on many queries over a large matrix. Each query takes O(m * n) in the worst case (a rectangle spanning the entire matrix), and with up to 10,000 queries that work is repeated from scratch every time even though the matrix never changes.
sumRegion call, initialize a sum variable to 0.row1 to row2.col1 to col2.matrix[row][col] to the running sum.Loading animation...
The next approach precomputes row-wise prefix sums so each row's contribution to a query becomes a single subtraction instead of a scan.
Compute prefix sums for each row independently. With a per-row prefix array, the sum of any segment within a row is one subtraction. A rectangle query then loops only over the rows from row1 to row2, taking each row's contribution in O(1) instead of scanning that row's columns.
This brings the per-query cost from O(m * n) down to O(m), and it is the direct one-dimensional version of the two-dimensional prefix sum in the next approach.
For each row i, build a prefix array where rowPrefix[i][j] = sum of matrix[i][0..j-1]. The sum of row i from column col1 to col2 is rowPrefix[i][col2 + 1] - rowPrefix[i][col1]. The leading zero at rowPrefix[i][0] is what lets col1 = 0 work without a special case.
rowPrefix[i][j] stores the sum of the first j elements in row i.sumRegion call, initialize a sum variable to 0.row1 to row2.rowPrefix[r][col2 + 1] - rowPrefix[r][col1].Loading animation...
Row prefixes still require a loop over up to m rows per query. The next approach precomputes sums in both dimensions at once, reducing every query to a fixed number of lookups regardless of rectangle size.
The 2D prefix sum precomputes one value per cell and answers every query in constant time using inclusion-exclusion.
Define a prefix sum matrix where prefix[i][j] stores the sum of all elements in the rectangle from (0, 0) to (i-1, j-1). Each entry is the sum of one full corner-anchored rectangle. Any arbitrary rectangle sum can then be expressed as a combination of four such corner rectangles.
To get the sum of the rectangle from (row1, col1) to (row2, col2), start with prefix[row2+1][col2+1], the sum of everything from the origin to the bottom-right corner. That overcounts: it includes the band above the target rectangle and the band to its left. Subtract both:
prefix[row1][col2+1] (everything above the rectangle)prefix[row2+1][col1] (everything to the left of the rectangle)The two bands overlap in the top-left corner region, so that corner has now been subtracted twice. Add it back once:
prefix[row1][col1] (top-left corner, double-subtracted)What remains is exactly the target rectangle: four lookups and three arithmetic operations per query.
Constructing the table uses the same inclusion-exclusion in reverse. The sum of the corner rectangle ending at (i, j) equals the cell matrix[i][j] plus the rectangle directly above it (prefix[i][j+1]) plus the rectangle directly to its left (prefix[i+1][j]), minus their shared overlap (prefix[i][j]), which both of those include. Because each prefix[i+1][j+1] depends only on entries with a smaller row or column, filling the table top-to-bottom, left-to-right guarantees every term is already computed when it is read.
(m+1) x (n+1), initialized to zeros. The extra row and column handle boundary cases cleanly (no special-casing row 0 or column 0).(i, j), compute: prefix[i+1][j+1] = matrix[i][j] + prefix[i][j+1] + prefix[i+1][j] - prefix[i][j].sumRegion(row1, col1, row2, col2) call, return: prefix[row2+1][col2+1] - prefix[row1][col2+1] - prefix[row2+1][col1] + prefix[row1][col1].Loading animation...