1. 程式人生 > >領釦(LeetCode)二維區域和檢索 個人題解

領釦(LeetCode)二維區域和檢索 個人題解

給定一個二維矩陣,計算其子矩形範圍內元素的總和,該子矩陣的左上角為 (row1, col1) ,右下角為 (row2, col2)。

Range Sum Query 2D
上圖子矩陣左上角 (row1, col1) = (2, 1) ,右下角(row2, col2) = (4, 3),該子矩形內元素的總和為 8。

示例:

給定 matrix = [
  [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]
]

sumRegion(2, 1, 4, 3) -> 8
sumRegion(1, 1, 2, 2) -> 11
sumRegion(1, 2, 2, 4) -> 12

說明:

  1. 你可以假設矩陣不可變。
  2. 會多次呼叫 sumRegion 方法
  3. 你可以假設 row1 ≤ row2 且 col1 ≤ col2。

 

對於這一題,一開始拿到以為是很簡單的,還想著為什麼會放在中等題裡面。

雖然知道可能會出現超時的問題,但是第一次寫還是嘗試了暴力遍歷求區域內值的和。答案雖然是正確的,當然顯而易見報錯了。超時。

後來想到了(其實還是參考了思路,拜託欸,我可是萌新,哪裡接觸過這種空間換時間的神奇操作 XD),其實,每個區域塊到左上角的值都可以簡化為上一個已經處理過的區域塊的加減乘除的取值,然後加上當前的值。同時,某個子區域的塊也能轉換成以上塊的加減乘除集合。

公式為:

(略)

程式碼如下:

class NumMatrix {
    int[][] matrix;
    int[][] markmatr;
    
    
    public NumMatrix(int[][] matrix) {
        this.matrix=matrix;
        int x=matrix.length;
        int y=x>0?matrix[0].length:0;
        markmatr=new int[x+1][y+1];
        for(int i=1;i<=x;i++)
        {
            
for(int j=1;j<=y;j++) { markmatr[i][j]=markmatr[i-1][j]+markmatr[i][j-1]-markmatr[i-1][j-1]+matrix[i-1][j-1]; } } } public int sumRegion(int row1, int col1, int row2, int col2) { int sum=0; sum=markmatr[row2+1][col2+1]-markmatr[row1][col2+1]-markmatr[row2+1][col1]+markmatr[row1][col1]; return sum; } }