一. 題目描述
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);
四. 小結
在構造輔助數組時,應考慮邊界問題和下標的轉換,否則容易出現越界等錯誤。