题目:
给定一个二维矩阵 matrix,以下类型的多个请求:
- 计算其子矩形范围内元素的总和,该子矩阵的 左上角 为
(row1, col1),右下角 为(row2, col2)。
实现 NumMatrix 类:
NumMatrix(int[][] matrix)给定整数矩阵matrix进行初始化int sumRegion(int row1, int col1, int row2, int col2)返回 左上角(row1, col1)、右下角(row2, col2)所描述的子矩阵的元素 总和 。
解法:
方法一:二维前缀和
前缀和矩阵NumMatrix.PrefixSum[i][j] 保存 满足0 <= x <= i;0 <= y <= j的所有matrix[x][y]的和。
则前缀和矩阵的生成关系为:PrefixSum[i][j] = PrefixSum[i - 1][j] + PrefixSum[i][j - 1] - PrefixSum[i - 1][j - 1] + matrix[i][j]
矩阵区域和的计算关系为:
sum = PrefixSum[row2][col2] - PrefixSum[row2][col1] - PrefixSum[row1][col2] + PrefixSum[row1 - 1][col1 - 1]
type NumMatrix struct {
PrefixSum [][]int
}
func Constructor(matrix [][]int) NumMatrix {
n := len(matrix)
m := len(matrix[0])
nMatrix := NumMatrix{
PrefixSum: make([][]int, n),
}
for i := 0; i < n; i ++ {
nMatrix.PrefixSum[i] = make([]int, m)
for j := 0; j < m; j ++ {
up, left, pre := 0, 0, 0
if i - 1 >= 0 && j - 1 >= 0 {
pre = nMatrix.PrefixSum[i - 1][j - 1]
}
if i - 1 >= 0 {
left = nMatrix.PrefixSum[i - 1][j]
}
if j - 1 >= 0 {
up = nMatrix.PrefixSum[i][j - 1]
}
nMatrix.PrefixSum[i][j] = up + left + matrix[i][j] - pre
}
}
fmt.Println(nMatrix.PrefixSum)
return nMatrix
}
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
// row1, col1 (point2) 矩形右下角
// row2, col2 (point1) 矩形左上角
up, left, pre := 0, 0, 0
if row1 - 1 >= 0 && col1 - 1 >= 0 {
pre = this.PrefixSum[row1 - 1][col1 - 1]
}
if col1 - 1 >= 0 {
left = this.PrefixSum[row2][col1 - 1]
}
if row1 - 1 >= 0 {
up = this.PrefixSum[row1 - 1][col2]
}
return this.PrefixSum[row2][col2] - up - left + pre
}
方法二:一维前缀和
假设m x n的矩阵,我们可以把矩阵看出m个一维数组,对每个一维数组用一维前缀和计算。
这种方式比较好理解,但是如果是频繁对区域进行+,-运算,则每次都要对m行进行O(1)操作,复杂度O(row2-row1)
type NumMatrix struct {
Sum [][]int
Matrix [][]int
}
func Constructor(matrix [][]int) NumMatrix {
m, n := len(matrix), len(matrix[0])
numMatrix := NumMatrix{make([][]int, m), matrix}
sum := 0
for i := range matrix {
numMatrix.Sum[i] = make([]int, n)
for j := range matrix[i] {
sum = sum + matrix[i][j]
numMatrix.Sum[i][j] = sum
}
}
return numMatrix
}
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
ans := 0
for i := row1; i <= row2; i ++ {
ans = ans + this.Sum[i][col2] - this.Sum[i][col1] + this.Matrix[i][col1]
}
return ans
}