Description
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2) 。
示例:
给定 matrix = [
[3, 0, 1, 4, 2],
[5, 6, 3, 2, 1],
[1, 2, 0, 1, 5],
[4, 1, 0, 1, 7],
[1, 0, 3, 0, 5]
]
sumRegion(2, 1, 4, 3) -> 8
sumRegion(1, 1, 2, 2) -> 11
sumRegion(1, 2, 2, 4) -> 12
思路
昨天动态规划的升级版。依然考虑打表。和昨天不同,求和矩阵有四个坐标。设sumRegion(a,b,c,d)=f((a,b),(c,d)),a≤c,b≤dsumRegion(a,b,c,d)=f((a,b),(c,d)),a\leq c,b\leq dsumRegion(a,b,c,d)=f((a,b),(c,d)),a≤c,b≤d,注意到如下状态转移公式:
f((a,b),(c,d))=f((0,0),(c,d))−f((0,0),(a,d))−f((0,0),(c,b))+f((0,0),(a,b))
f((a,b),(c,d))=f((0,0),(c,d))-f((0,0),(a,d))-f((0,0),(c,b))+f((0,0),(a,b))
f((a,b),(c,d))=f((0,0),(c,d))−f((0,0),(a,d))−f((0,0),(c,b))+f((0,0),(a,b))
也就是把四个参数简化为两个参数,减少了打表的空间。
接下来考虑怎么打表。设f((0,0),(a,b))=g(a,b)f((0,0),(a,b))=g(a,b)f((0,0),(a,b))=g(a,b),注意到状态转移公式:
g(0,0)=Matrix[0][0]g(a,b+1)=g(a,b)+∑j=0aMatrix[j][b+1]
g(0,0)=Matrix[0][0]\\
g(a,b+1)=g(a,b)+\sum_{j=0}^{a}Matrix[j][b+1]
g(0,0)=Matrix[0][0]g(a,b+1)=g(a,b)+j=0∑aMatrix[j][b+1]
sum部分可以考虑打表进行进一步空间换时间?
总之这个题就是这样,顺着公式写就好了。
下面是官方题解:
代码
class NumMatrix:
def __init__(self, matrix: List[List[int]]):
m, n = len(matrix), (len(matrix[0]) if matrix else 0)
self.sums = [[0] * (n + 1) for _ in range(m + 1)]
_sums = self.sums
for i in range(m):
for j in range(n):
_sums[i + 1][j + 1] = _sums[i][j + 1] + _sums[i + 1][j] - _sums[i][j] + matrix[i][j]
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
_sums = self.sums
return _sums[row2 + 1][col2 + 1] - _sums[row1][col2 + 1] - _sums[row2 + 1][col1] + _sums[row1][col1]
打卡。