0308. 二维区域和检索 - 矩阵可修改
大约 3 分钟
--- 
0308. 二维区域和检索 - 矩阵可修改
- 标签:设计、树状数组、线段树、数组、矩阵
- 难度:中等
题目链接
题目大意
描述:
给定一个二维矩阵 。
要求:
处理以下类型的多个查询:
- 更新 中单元格的值。
- 计算由 左上角 和 右下角 定义的 内矩阵元素的和。
实现 NumMatrix 类:
NumMatrix(int[][] matrix)用整数矩阵 初始化对象。void update(int row, int col, int val)更新 的值到 。int sumRegion(int row1, int col1, int row2, int col2)返回矩阵 中指定矩形区域元素的和,该区域由左上角 和 右下角 界定。
说明:
- 。
- 。
- 。
- 。
- 。
- 。
- 。
- 。
- 。
- 最多调用 次
sumRegion和update方法。
示例:
- 示例 1:

输入
["NumMatrix", "sumRegion", "update", "sumRegion"]
[[[[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]]], [2, 1, 4, 3], [3, 2, 2], [2, 1, 4, 3]]
输出
[null, 8, null, 10]
解释
NumMatrix numMatrix = new NumMatrix([[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]]);
numMatrix.sumRegion(2, 1, 4, 3); // 返回 8 (即, 左侧红色矩形的和)
numMatrix.update(3, 2, 2); // 矩阵从左图变为右图
numMatrix.sumRegion(2, 1, 4, 3); // 返回 10 (即,右侧红色矩形的和)解题思路
思路 1:二维前缀和数组
算法思路:
使用二维前缀和数组来快速计算矩形区域的和。二维前缀和数组 表示从 到 的矩形区域内所有元素的和。
对于查询矩形区域 到 的和,可以使用容斥原理:
具体实现:
初始化:
- 创建二维前缀和数组 ,大小为 ,其中 和 分别是矩阵的行数和列数。
- 计算前缀和:
更新操作:
- 计算差值
- 更新原矩阵:
- 更新前缀和数组:从 开始,所有受影响的区域都需要加上
查询操作:
- 使用容斥原理计算指定矩形区域的和
思路 1:代码
from typing import List
class NumMatrix:
def __init__(self, matrix: List[List[int]]):
"""初始化二维前缀和数组"""
self.matrix = matrix
self.m, self.n = len(matrix), len(matrix[0])
# 创建前缀和数组,大小为 (m+1) x (n+1)
self.prefix = [[0] * (self.n + 1) for _ in range(self.m + 1)]
# 计算前缀和
for i in range(1, self.m + 1):
for j in range(1, self.n + 1):
self.prefix[i][j] = (self.prefix[i-1][j] +
self.prefix[i][j-1] -
self.prefix[i-1][j-1] +
matrix[i-1][j-1])
def update(self, row: int, col: int, val: int) -> None:
"""更新矩阵元素并维护前缀和数组"""
# 计算差值
diff = val - self.matrix[row][col]
self.matrix[row][col] = val
# 更新前缀和数组
for i in range(row + 1, self.m + 1):
for j in range(col + 1, self.n + 1):
self.prefix[i][j] += diff
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
"""使用容斥原理计算矩形区域和"""
return (self.prefix[row2+1][col2+1] -
self.prefix[row1][col2+1] -
self.prefix[row2+1][col1] +
self.prefix[row1][col1])
# Your NumMatrix object will be instantiated and called as such:
# obj = NumMatrix(matrix)
# obj.update(row,col,val)
# param_2 = obj.sumRegion(row1,col1,row2,col2)思路 1:复杂度分析
- 时间复杂度:
- 构造函数:,其中 和 分别是矩阵的行数和列数。需要计算整个前缀和数组。
update函数:,最坏情况下需要更新整个前缀和数组。sumRegion函数:,直接通过前缀和数组计算。
- 空间复杂度:,需要存储前缀和数组。