一、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;
}
}
和求子矩陣的和沒啥區別,要處理左上角座標稍微麻煩一點。
複雜度分析
- 時間複雜度:,
- 空間複雜度:,