类别:数组 前缀和数组
题目:
想法一:
代码:
class NumMatrix {
int[][] sums;
public NumMatrix(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
sums = new int[m][n];
int i,j,a,b;
for(i=0;i<m;i++){
for(j=0;j<n;j++){
sums[i][j]=0;
for(a=0;a<=i;a++){
for(b=0;b<=j;b++){
sums[i][j]+=matrix[a][b];
}
}
}
}
//计算左上角方阵和
}
public int sumRegion(int row1, int col1, int row2, int col2) {
if(col1==0 && row1==0){
return sums[row2][col2];
}else if(col1==0){
return sums[row2][col2]-sums[row1-1][col2];
}else if(row1==0){
return sums[row2][col2]-sums[row2][col1-1];
}else{
return sums[row2][col2]-sums[row2][col1-1]-sums[row1-1][col2]+sums[row1-1][col1-1];
}
}
}
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/
结果:超时
优化:计算矩阵的子矩阵和时,时间复杂度太大,导致超时。使用巧妙算法规避循环累加!
代码:
class NumMatrix {
int[][] sums;
public NumMatrix(int[][] matrix) {
int m = matrix.length;
if (m > 0) {
int n = matrix[0].length;
sums = new int[m + 1][n + 1];
//比原矩阵大一圈,第0行/列存放全0
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
//计算左上角矩阵和:巧妙算法
sums[i + 1][j + 1] = sums[i][j + 1] + sums[i + 1][j] - sums[i][j] + matrix[i][j];
}
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
return sums[row2 + 1][col2 + 1] - sums[row1][col2 + 1] - sums[row2 + 1][col1] + sums[row1][col1];
}
}
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/
结果: