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.
Example:
Given 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
题目
给定元素不变的矩阵,求各种子矩阵和。
思路
Given 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
(2,1) 为黄色range左上角的坐标, 所在坐标对应的点为2
(4,3) 为黄色range右下角的坐标, 所在坐标对应的点为0
黄色range中 2 + 0 + 0 + 1 + 0 + 1 + 0 + 3 + 0 = 8
比如, input matrix为
2 0 -3 4 6 3 2 -1 5 4 7 3 2 -6 8 1
多加一行一列方便写code,变成dp matrix为
0 0 0 0 0 0 2 0 -3 4 0 6 3 2 -1 0 5 4 7 3 0 2 -6 8 1
开始fill dp matrix
dp[i][j]表示sum of rectangle from (0,0) to matrix (i-1, j-1)
0 0 0 0 0 0 2 2 -1 3 //-> first row: easy to fill(累加) 0 0 0
0 0 0 0 0 0 2 2 -1 3 0 8 0 13 0 15
// -> first col: easy to fill(累加)
0 0 0 0 0 0 2 2 -1 3 0 8 X -> dp[i][j] = dp[i-1][j] // 正上方 2 0 13 + dp[i][j-1] // 正左方 8 0 15 + matrix [i-1][j-1] // input matrix 该位置值
- dp[i-1][j-1] // 左上角 2 ,重复加了两次需要减去一次
代码
1 class NumMatrix { 2 private int[][] dp; 3 4 /* 1.build and fill dp matrix in O(m*n) time */ 5 public NumMatrix(int[][] matrix) { 6 int row = 0; 7 int col = 0; 8 if (matrix.length != 0) { 9 row = matrix.length; 10 col = matrix[0].length; 11 } 12 dp = new int[row + 1][col + 1]; 13 for (int i = 1; i < dp.length; i++) { 14 for (int j = 1; j < dp[0].length; j++) { 15 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + matrix[i - 1][j - 1] - dp[i - 1][j - 1]; 16 } 17 } 18 19 } 20 21 /*2. query in O(1) time */ 22 public int sumRegion(int row1, int col1, int row2, int col2) { 23 /* coz dp matrix has size 1 greater one more than original matrix*/ 24 row1++; 25 col1++; 26 row2++; 27 col2++; 28 return dp[row2][col2] - dp[row1 - 1][col2] - dp[row2][col1 - 1] + dp[row1 - 1][col1 - 1]; 29 } 30 }
代码
1 class NumMatrix { 2 private int[][] dp; 3 4 /* 1.build and fill dp matrix in O(m*n) time */ 5 public NumMatrix(int[][] matrix) { 6 int row = 0; 7 int col = 0; 8 if (matrix.length != 0) { 9 row = matrix.length; 10 col = matrix[0].length; 11 } 12 dp = new int[row + 1][col + 1]; 13 for (int i = 1; i < dp.length; i++) { 14 for (int j = 1; j < dp[0].length; j++) { 15 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + matrix[i - 1][j - 1] - dp[i - 1][j - 1]; 16 } 17 } 18 19 } 20 21 /*2. query in O(1) time */ 22 public int sumRegion(int row1, int col1, int row2, int col2) { 23 /* coz dp matrix has size 1 greater one more than original matrix*/ 24 row1++; 25 col1++; 26 row2++; 27 col2++; 28 return dp[row2][col2] - dp[row1 - 1][col2] - dp[row2][col1 - 1] + dp[row1 - 1][col1 - 1]; 29 } 30 }