一、Problem
二、Solution
方法一:暴力
一开始把 dir 数组也弄出来的了,这是错误思想,因为这里需要将 tx 与 ty 一起判断,而一起判断会导致一个不合法就 pass 掉了,其实没必要,直接用 min、max 来取出当前座标能到达的最远座标即可。
int[][] d = { {1,0},{0,-1},{0,1},{-1,0}, {-1,-1}, {1,1} };
class Solution {
public int[][] matrixBlockSum(int[][] mat, int K) {
int r = mat.length, c = mat[0].length, s[][] = new int[r][c];
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) {
int lowi = Math.max(i-K, 0), higi = Math.min(i+K, r-1);
int lowj = Math.max(j-K, 0), higj = Math.min(j+K, c-1);
for (int ii = lowi; ii <= higi; ii++)
for (int jj = lowj; jj <= higj; jj++)
s[i][j] += mat[ii][jj];
}
return s;
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:二维前缀和
得到前缀和后,第一感觉是求出右下角座标就可以求出答案,疏忽了左下角的座标。
class Solution {
public int[][] matrixBlockSum(int[][] g, int K) {
int r = g.length, c = g[0].length, s[][] = new int[r+1][c+1];
for (int i = 1; i <= r; i++)
for (int j = 1; j <= c; j++) {
s[i][j] = g[i-1][j-1] + s[i-1][j] + s[i][j-1] - s[i-1][j-1];
}
int[][] a= new int[r][c];
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) {
int mx = Math.min(i + K, r-1), my = Math.min(j + K, c-1);
a[i][j] = s[mx+1][my+1];
}
return a;
}
}
class Solution {
public int[][] matrixBlockSum(int[][] g, int K) {
int r = g.length, c = g[0].length, s[][] = new int[r+1][c+1];
for (int i = 1; i <= r; i++)
for (int j = 1; j <= c; j++) {
s[i][j] = g[i-1][j-1] + s[i-1][j] + s[i][j-1] - s[i-1][j-1];
}
int[][] a = new int[r][c];
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) {
int lx = Math.max(i - K, 0), ly = Math.max(j - K, 0);
int rx = Math.min(i + K, r-1), ry = Math.min(j + K, c-1);
a[i][j] = s[rx+1][ry+1] - s[rx+1][ly] - s[lx][ry+1] + s[lx][ly];
}
return a;
}
}
和求子矩阵的和没啥区别,要处理左上角座标稍微麻烦一点。
复杂度分析
- 时间复杂度:,
- 空间复杂度:,