304 Range Sum Query 2D - Immutable
Prefix Sum的2D matrix 扩展
- pre-processing to get prefix sum matrix (the method is similar to DP in 2D)
- use dp to get the regional sum of interest in O(1) time
Approach 1 Prefix Sum
Prefix sum --> 2D的思维扩展, intuition is by inclusion-exclusion,

The idea of inclusion-exclusion is basically,
Then we need to pre-processing and compute a matrix such that we can get the accumulative sum from origin (0,0) to (x,y). This idea is exactly like DP in 2D, as illustrated in the figure below,

The definition of
dp[i][j]: regional sum from (0,0) to (i,j) where i and j are the row and column number.
Generalize it
After you have to pre-processed regional sum matrix, the SUM(ABCD) can be computed by information in dp matrix.
Code Implementation
class NumMatrix:
def __init__(self, matrix: List[List[int]]):
self.matrix = matrix
# number of rows and columns
rows,cols = len(matrix),len(matrix[0])
# initialize prefix sum (but in 2D): (0,0) to (x,y)的regional sum
# 第一行和第一列卫boundary nodes
dp = [[0 for _ in range(cols+1)] for _ in range(rows+1)]
for i in range(rows):
for j in range(cols):
dp[i+1][j+1] = dp[i+1][j] + dp[i][j+1] + matrix[i][j] - dp[i][j]
self.dp = dp
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
"""
(row1,col1) - upper left
(row2,col2) - lower right
"""
return self.dp[row2+1][col2+1] - self.dp[row1][col2+1] - self.dp[row2+1][col1] + self.dp[row1][col1]
We can also use a matrix of tuple so we don't worry about boundary as well. Although you don't have to deal with boundary, but you cost more time due to it's generally slower to access a hash table than a list.
from collections import defaultdict
class NumMatrix:
def __init__(self, matrix: List[List[int]]):
self.matrix = matrix
dp = defaultdict(int)
rows,cols = len(matrix),len(matrix[0])
for i in range(rows):
for j in range(cols):
dp[(i,j)] = dp[(i-1,j)] + dp[(i,j-1)] - dp[(i-1,j-1)] + matrix[i][j]
self.dp = dp
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
return self.dp[(row2,col2)] - self.dp[(row2,col1-1)] - self.dp[(row1-1,col2)] + self.dp[(row1-1,col1-1)]