Range Sum Query 2D - Immutable
The problem requires us to perform multiple queries to find the sum of elements in a specific rectangle inside a 2D matrix. The challenge here is to design the solution in such a way that each query operates in ( O(1) ) time complexity.
To achieve this, we can precompute the prefix sum for each cell (i, j), which includes the sum of all cells above and to the left of it. We can then utilize this information to calculate the sum of any rectangle within the matrix in constant time.
Here’s a step-by-step explanation of the solution:
Precompute the Prefix Sum: Compute a new matrix prefixSum
of the same size, where prefixSum[i][j]
contains the sum of the elements from matrix[0][0]
to matrix[i][j]
.
Calculate the Sum of a Specific Rectangle: To get the sum of elements inside the rectangle defined by (row1, col1)
and (row2, col2)
, we can use the following formula:
[
\text{sum} = \text{prefixSum}[row2][col2] - \text{prefixSum}[row1 - 1][col2] - \text{prefixSum}[row2][col1 - 1] + \text{prefixSum}[row1 - 1][col1 - 1]
]
Here’s the code:
1
2
3
4
5
6
7
8
9
10
11
12
| class NumMatrix:
def __init__(self, matrix: List[List[int]]):
m, n = len(matrix), len(matrix[0])
self.prefixSum = [[0] * (n + 1) for _ in range(m + 1)]
# Calculate prefix sum
for i in range(m):
for j in range(n):
self.prefixSum[i + 1][j + 1] = matrix[i][j] + self.prefixSum[i][j + 1] + self.prefixSum[i + 1][j] - self.prefixSum[i][j]
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
return self.prefixSum[row2 + 1][col2 + 1] - self.prefixSum[row1][col2 + 1] - self.prefixSum[row2 + 1][col1] + self.prefixSum[row1][col1]
|
By precomputing the prefix sum, the sumRegion
method can perform each query in constant time, i.e., ( O(1) ).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| class NumMatrix
=begin
:type matrix: Integer[][]
=end
def initialize(matrix)
rows = matrix.length
cols = matrix[0].length rescue 0
if rows == 0 || cols == 0
return
end
@dp = Array.new(rows) { Array.new(cols+1, 0)}
for row in (0..rows-1)
for col in (0..cols-1)
@dp[row][col+1] = @dp[row][col] + matrix[row][col]
end
end
end
=begin
:type row1: Integer
:type col1: Integer
:type row2: Integer
:type col2: Integer
:rtype: Integer
=end
def sum_region(row1, col1, row2, col2)
sum = 0
for row in (row1..row2)
sum += @dp[row][col2+1] - @dp[row][col1]
end
sum
end
end
# Your NumMatrix object will be instantiated and called as such:
# obj = NumMatrix.new(matrix)
# param_1 = obj.sum_region(row1, col1, row2, col2)
|