leetcode 1314矩阵区域和
这题不使用其他方法强行四重for也可以过,但是内存和时间占用可谓惨不忍睹。
本题可采用矩阵前缀和的方法解决,从内存占用到时间处理上都会好很多。
第一遍代码如下:
/*感觉这题有点奇怪的简单...
先建立一个和原矩阵相同大小的矩阵
然后使用四个判断把rmin rmax,cmin,cmax确定下来
最后使用上述四个参数进行计算
*/
class Solution {
public int[][] matrixBlockSum(int[][] mat, int K) {
int m = mat.length;
int n = mat[0].length;
int rmin = 0,rmax = 0,cmin = 0,cmax = 0;
int array[][] = new int [m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
rmin = Math.max(i - K ,0);
cmin = Math.max(j - K ,0);
rmax = Math.min(i + K ,m - 1);
cmax = Math.min(j + K, n - 1);
int sum = 0;
for(int temp1 = rmin; temp1 <= rmax; temp1++){
for(int temp2 = cmin; temp2 <= cmax; temp2++){
sum += mat[temp1][temp2];
}
}
array[i][j] = sum;
}
}
return array;
}
}
使用前缀和矩阵改良后的代码
/*算法学习结束后改正的答案:
首先建立一个比原矩阵多一行一列的前缀和矩阵dp
初始化的时候首先将第一行第一列初始化为0
而后按从左到右从上到下的顺序初始化
而后使用算法面积计算方法可以得到(0,0)到(i,j)的面积
最后取结果的时候用同样的方法取得array结果
可以让时间复杂度精简很多
第一次计算是左下加右上减左上重复加右下没算的
第二次计算是整个大面积减去左边一整块的面积和上面一整块的面积
最后减去左上重叠面积
*/
class Solution {
public int[][] matrixBlockSum(int[][] mat, int K) {
int m = mat.length;
int n = mat[0].length;
int rmin = 0,rmax = 0,cmin = 0,cmax = 0;
int array[][] = new int [m][n];
int dp[][] = new int [m + 1][n + 1];
for(int i = 0; i <= m; i++){
dp[i][0] = 0;
}
for(int i = 0; i <= n; i++){
dp[0][i] = 0;
}
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + mat[i - 1][j - 1];//此处mat对应dp[i][j]
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
rmin = Math.max(i - K ,1);
cmin = Math.max(j - K ,1);
rmax = Math.min(i + K ,m);
cmax = Math.min(j + K, n);
array[i][j] =dp[rmax + 1][cmax + 1] - dp[rmin][cmax + 1] - dp[rmax + 1][cmin] + dp[rmin][cmin];
}
}
return array;
}
}
时间击败88%
总结
算法的学习真不是一撮而就的过程,下次再碰见类似的时间击败数可得小心了,大概率是算法不过关。