一. 题目描述
Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1)
and lower right corner (row2, col2)
.
The above rectangle (with the red border) is defined by (row1, col1) = (2, 1)
and (row2, col2) = (4, 3)
, which contains sum = 8
.
二. 题目分析
题目大意是,给定一个二维矩阵,计算从下标(row1, col1)
到下标: (row2, col2)
的子矩阵的和。题目给出了几个测试用例。
注意事项中提到:
- 假设矩阵不会改变;
- sumRegion(查询)函数会调用很多次;
- 假设
row1 ≤ row2
, 并且col1 ≤ col2
。
该题的重点是使当多次调用sumRegion函数时,算法能保持高效,因此最直观的方法是使用空间换取时间,通过构造辅助数组sumRecord
,sumRecord[i][j]
表示从下标(0, 0)
到(x, y)
的子矩阵的和(考虑到边界问题,辅助数组sumRecord
大小设为(m + 1) * (n + 1)
,其中m
和n
分别为数组matrix
的行数和列数),使得题目转化为求取矩形边界的问题,如下面所示。
没有手动画图,引用网上的系列图片进行解释:
+-----+-+-------+ +--------+-----+ +-----+---------+ +-----+--------+
| | | | | | | | | | | | |
| | | | | | | | | | | | |
+-----+-+ | +--------+ | | | | +-----+ |
| | | | = | | + | | | - | |
+-----+-+ | | | +-----+ | | |
| | | | | | | |
| | | | | | | |
+---------------+ +--------------+ +---------------+ +--------------+
sumRecord[i][j] = sumRecord[i-1][j] + sumRecord[i][j-1] - sumRecord[i-1][j-1] +
matrix[i-1][j-1]
这是小学学过的简单的矩形求面积方法,对于本题正好适用。
三. 示例代码
class NumMatrix {
public:
NumMatrix(vector<vector<int>> &matrix) {
int m = matrix.size();
int n = m > 0 ? matrix[0].size() : 0;
sumRecord = vector<vector<int>>(m + 1, vector<int>(n + 1, 0));
// 由于sumRegion函数可能被调用多次,因此使用辅助数组sumRecord用于
// 记录matrix中坐标(0,0)到任一下标(i,j)之间矩形框内元素的值,这样
// 每次调用sumRegion函数时只需查询sumRecord里的值并进行简单运算即可
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
sumRecord[i][j] = matrix[i - 1][j - 1] + sumRecord[i - 1][j] + sumRecord[i][j - 1] - sumRecord[i - 1][j - 1];
}
int sumRegion(int row1, int col1, int row2, int col2) {
return sumRecord[row2 + 1][col2 + 1] - sumRecord[row1][col2 + 1] - sumRecord[row2 + 1][col1] + sumRecord[row1][col1];
}
private:
vector<vector<int>> sumRecord;
};
// Your NumMatrix object will be instantiated and called as such:
// NumMatrix numMatrix(matrix);
// numMatrix.sumRegion(0, 1, 2, 3);
// numMatrix.sumRegion(1, 2, 3, 4);
四. 小结
在构造辅助数组时,应考虑边界问题和下标的转换,否则容易出现越界等错误。
时间: 2024-10-10 23:00:06