Shubham Sourabhthe room · director's cutplain résumé
Room 04 · The Grind — Arrays & Hashing

Range Sum Query 2D Immutable

MEDIUM✓ CHIP-TIMEDLC #304 — FULL STATEMENT

The briefingthe full drill, in my own words

The drill: Answer many rectangle-sum queries against a fixed 2D grid — the grid never changes after construction, only the query rectangles do.

A fixed 2D grid of integers is handed over once at construction, and after that only one kind of question ever gets asked: what does a given rectangle of that grid sum to?

The grid itself never changes after it's built — no updates, no insertions — only the query rectangles vary, arriving one at a time and each needing an answer.

A rectangle query names its top-left and bottom-right corners, inclusive on both ends, and expects back the sum of every cell inside that boundary.

  • the grid can be up to a couple hundred rows and columns
  • cell values may be negative, zero, or positive
  • the grid is immutable after construction — queries only, no updates
  • query rectangle corners are always valid, inclusive coordinates within the grid
EX 01
NumMatrix([[2, -1, 4, 0], [3, 5, -2, 1], [0, 2, 3, -4], [1, 1, 2, 6]])
sumRegion(0, 0, 3, 3) → 23
sumRegion(1, 1, 2, 2) → 8
sumRegion(0, 0, 0, 0) → 2
sumRegion(3, 3, 3, 3) → 6
full grid, a sub-square, and two single cells
EX 02
NumMatrix([[7]])
sumRegion(0, 0, 0, 0) → 7
1x1 matrix
EX 03
NumMatrix([[1, 2, 3, 4, 5]])
sumRegion(0, 0, 0, 4) → 15
sumRegion(0, 1, 0, 3) → 9
single row

The hintstake only what you need

HINT 1 THE NUDGE

Summing a rectangle by walking every cell inside it is correct, but if the grid gets asked about again and again, that walk repeats work every single time. What could you compute once, before the first query even arrives?

HINT 2 THE STRUCTURE

A running total from the top-left corner to any cell tells you the sum of that whole sub-rectangle in one lookup — build that table once at construction.

HINT 3 ONE STEP FROM THE ANSWER

sumRegion(r1,c1,r2,c2) = prefix[r2+1][c2+1] − prefix[r1][c2+1] − prefix[r2+1][c1] + prefix[r1][c1] — inclusion-exclusion adds the doubly-subtracted top-left corner back in.

Coach's boardthe pattern, step by step

THE RUNNING CORNERPATTERN · 2-D PREFIX SUMmatrix = [[1, 2], [3, 4]] · sumRegion(0,0,1,1)
0
0
0
0
0
STEP 1

matrix = [[1,2],[3,4]]. Build a prefix-sum table once, padded with a zero row and column.

STEP 1 / 7 · ← → WORK TOO

The splitstwo paces, two languages

grind/range-sum-query-2d-immutable.py — RACE PACE
LANG ▸
PACE ▸
class NumMatrix:
    def __init__(self, matrix: List[List[int]]):
        rows = len(matrix)
        cols = len(matrix[0]) if rows else 0
        self.prefix = [[0] * (cols + 1) for _ in range(rows + 1)]
        for r in range(rows):
            for c in range(cols):
                self.prefix[r + 1][c + 1] = (
                    matrix[r][c] + self.prefix[r][c + 1] + self.prefix[r + 1][c] - self.prefix[r][c]
                )

    def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
        p = self.prefix
        return p[row2 + 1][col2 + 1] - p[row1][col2 + 1] - p[row2 + 1][col1] + p[row1][col1]
TIME O(ROWS·COLS) BUILD, O(1) PER QUERYSPACE O(ROWS·COLS)PYTHON · RACE PACE · 14 LN

✓ CHIP-TIMEDALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED