leetcode筆記:Range Sum Query 2D - Immutable

一. 題目描述

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函數時,算法能保持高效,因此最直觀的方法是使用空間換取時間,通過構造輔助數組sumRecordsumRecord[i][j]表示從下標(0, 0)(x, y)的子矩陣的和(考慮到邊界問題,輔助數組sumRecord大小設爲(m + 1) * (n + 1),其中mn分別爲數組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);

四. 小結

在構造輔助數組時,應考慮邊界問題和下標的轉換,否則容易出現越界等錯誤。

發佈了249 篇原創文章 · 獲贊 99 · 訪問量 115萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章