文章目录
一【题目类别】
- 矩阵
二【题目难度】
- 中等
三【题目编号】
- 304.二维区域和检索-矩阵不可变
四【题目描述】
- 给定一个二维矩阵 matrix,以下类型的多个请求:
- 计算其子矩形范围内元素的总和,该子矩阵的 左上角 为 (row1, col1) ,右下角 为 (row2, col2) 。
- 实现 NumMatrix 类:
- NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进行初始化
- int sumRegion(int row1, int col1, int row2, int col2) 返回左上角 (row1, col1) 、右下角 (row2, col2) 所描述的子矩阵的元素总和。
五【题目示例】
- 示例 1:
- 输入:
- ["NumMatrix","sumRegion","sumRegion","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],[1,1,2,2],[1,2,2,4]]
- 输出:
- [null, 8, 11, 12]
- 解释:
- 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); // return 8 (红色矩形框的元素总和)
- numMatrix.sumRegion(1, 1, 2, 2); // return 11 (绿色矩形框的元素总和)
- numMatrix.sumRegion(1, 2, 2, 4); // return 12 (蓝色矩形框的元素总和)
- 输入:
六【题目提示】
- m = = m a t r i x . l e n g t h m == matrix.length m==matrix.length
- n = = m a t r i x [ i ] . l e n g t h n == matrix[i].length n==matrix[i].length
- 1 < = m , n < = 200 1 <= m, n <= 200 1<=m,n<=200
- − 1 0 5 < = m a t r i x [ i ] [ j ] < = 1 0 5 -10^5 <= matrix[i][j] <= 10^5 −105<=matrix[i][j]<=105
- 0 < = r o w 1 < = r o w 2 < m 0 <= row1 <= row2 < m 0<=row1<=row2<m
- 0 < = c o l 1 < = c o l 2 < n 0 <= col1 <= col2 < n 0<=col1<=col2<n
- 最多调用 1 0 4 次 s u m R e g i o n 方法 最多调用 10^4 次 sumRegion 方法 最多调用104次sumRegion方法
七【解题思路】
- 利用前缀和的思想
- 新建一个二维数组,这个二维数组比原来的二维数组多一列,因为二维数组的每个位置都存储了之前元素的和,故多添加的一列就存储了原来二维数组最后一列的元素及之前值的和,我们只需要按照这个规律遍历填充这个新的二维数组即可
- 对于传入的二维区域,我们只需要逐行的利用前缀和进行计算求和
- 最后返回结果即可
八【时间频度】
- 时间复杂度: O ( m n ) O(mn) O(mn), m 、 n m、n m、n分别为传入的二维数组的行数和列数
- 空间复杂度: O ( m n ) O(mn) O(mn), m 、 n m、n m、n分别为传入的二维数组的行数和列数
九【代码实现】
- Java语言版
java
class NumMatrix {
int[][] sums;
public NumMatrix(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
sums = new int[m][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];
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
int res = 0;
for(int i = row1;i <= row2;i++){
res += sums[i][col2 + 1] - sums[i][col1];
}
return res;
}
}
- C语言版
c
typedef struct
{
int** sums;
int sumsSize;
} NumMatrix;
NumMatrix* numMatrixCreate(int** matrix, int matrixSize, int* matrixColSize)
{
int m = matrixSize;
int n = matrixColSize[0];
NumMatrix* obj = (NumMatrix*)malloc(sizeof(NumMatrix));
obj->sums = (int**)malloc(sizeof(int*) * m);
obj->sumsSize = m;
for(int i = 0;i < m;i++)
{
obj->sums[i] = (int*)malloc(sizeof(int) * (n + 1));
}
for(int i = 0;i < m;i++)
{
for(int j = 0;j < n;j++)
{
obj->sums[i][j + 1] = obj->sums[i][j] + matrix[i][j];
}
}
return obj;
}
int numMatrixSumRegion(NumMatrix* obj, int row1, int col1, int row2, int col2)
{
int res = 0;
for(int i = row1;i <= row2;i++)
{
res += obj->sums[i][col2 + 1] - obj->sums[i][col1];
}
return res;
}
void numMatrixFree(NumMatrix* obj)
{
for(int i = 0;i < obj->sumsSize;i++)
{
free(obj->sums[i]);
}
free(obj);
}
- Python语言版
python
class NumMatrix:
def __init__(self, matrix: List[List[int]]):
m = len(matrix)
n = len(matrix[0])
self.sums = [[0] * (n + 1) for _ in range(m)]
for i in range(0, m):
for j in range(0, n):
self.sums[i][j + 1] = self.sums[i][j] + matrix[i][j]
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
res = 0
for i in range(row1, row2 + 1):
res += self.sums[i][col2 + 1] - self.sums[i][col1]
return res
- C++语言版
cpp
class NumMatrix {
public:
vector<vector<int>> sums;
NumMatrix(vector<vector<int>>& matrix) {
int m = matrix.size();
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 res = 0;
for(int i = row1;i <= row2;i++){
res += sums[i][col2 + 1] - sums[i][col1];
}
return res;
}
};
十【提交结果】
-
Java语言版
-
C语言版
-
Python语言版
-
C++语言版