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
Note:
- You may assume that the matrix does not change.
- There are many calls to sumRegion function.
- You may assume that row1 ≤ row2 and col1 ≤ col2.
public class NumMatrix {
public int[][] matrixSums;
/**
* 构造函数
* @param matrix
*/
public NumMatrix(int[][] matrix) {
matrixSums = null;
if (matrix.length > 0 && matrix[0].length > 0) {
matrixSums = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (i == 0) {
if (j == 0) {
matrixSums[i][j] = matrix[i][j];
} else {
matrixSums[i][j] = matrixSums[i][j - 1] + matrix[i][j];
}
} else {
if (j == 0) {
matrixSums[i][j] = matrixSums[i - 1][j] + matrix[i][j];
} else {
matrixSums[i][j] = matrixSums[i - 1][j] +
(matrixSums[i][j - 1] - matrixSums[i - 1][j - 1]) +
matrix[i][j];
}
}
}
}
}
}
/**
* 给出左上角、右下角坐标,计算矩形区域内的元素和
* @param row1
* @param col1
* @param row2
* @param col2
* @return
*/
public int sumRegion(int row1, int col1, int row2, int col2) {
if (matrixSums == null || row1 > row2 || col1 > col2) {
return 0;
}
if (row1 == 0 && col1 == 0) {
return matrixSums[row2][col2];
} else if (row1 == 0) {
return matrixSums[row2][col2] - matrixSums[row2][col1 - 1];
} else if (col1 == 0) {
return matrixSums[row2][col2] - matrixSums[row1 - 1][col2];
} else {
return matrixSums[row2][col2] - matrixSums[row1 - 1][col2] -
(matrixSums[row2][col1 - 1] - matrixSums[row1 - 1][col1 - 1]);
}
}
}
// 可以建立一个与给定矩阵行、列数相同的中间矩阵matrixSums,matrixSums中的每个位置的元素值,是原矩阵matrix中所有行数、列数不大于该位置的元素值的和。在调用sumRegion函数时,可以通过中间矩阵matrixSums快速计算出结果。
//右下减右上减左下加左上就行