题目如下
给定一个二维矩阵 matrix,以下类型的多个请求:
计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2) 。
实现 NumMatrix 类:
NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进行初始化
int sumRegion(int row1, int col1, int row2, int col2) 返回左上角 (row1, col1) 、右下角 (row2, col2) 的子矩阵的元素总和。
示例
解题思路
一维前缀和
初始化时对矩阵的每一行计算前缀和,检索时对二维区域中的每一行计算子数组和,然后对每一行的子数组和计算总和。
具体实现方面,创建 m 行 n+1 列的二维数组 sums,其中 m 和 n 分别是矩阵matrix 的行数和列数,sums[i] 为matrix[i] 的前缀和数组。将 sums 的列数设为n+1 的目的是为了方便计算每一行的子数组和,不需要对 col 1=0 的情况特殊处理。
class NumMatrix
{
public:
vector<vector<int>> sums;
NumMatrix(vector<vector<int>>& matrix)
{
int m = matrix.size();
if (m > 0)
{
int n = matrix[0].size();
sums.resize(m, vector<int>(n + 1));
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
sums[i][j + 1] = sums[i][j] + matrix[i][j];
}
}
}
}
int sumRegion(int row1, int col1, int row2, int col2)
{
int sum = 0;
for (int i = row1; i <= row2; i++)
{
sum += sums[i][col2 + 1] - sums[i][col1];
}
return sum;
}
};
复杂度分析
时间复杂度:初始化 O(mn),每次检索 O(m),其中 m 和 n 分别是矩阵 matrix 的行数和列数。
初始化需要遍历矩阵 matrix 计算二维前缀和,时间复杂度是 O(mn)。
每次检索需要对二维区域中的每一行计算子数组和,二维区域的行数不超过 m,计算每一行的子数组和的时间复杂度是 O(1),因此每次检索的时间复杂度是O(m)。
空间复杂度:O(mn),其中 m 和 n 分别是矩阵matrix 的行数和列数。需要创建一个 m 行n+1 列的前缀和数组sums。