矩陣區域和(medium)
- 題?描述:
- 解法:
- 代碼
- Java 算法代碼:
- C++ 算法代碼:
題?描述:
題?鏈接:1314. 矩陣區域和
給你?個 m x n 的矩陣 mat 和?個整數 k ,請你返回?個矩陣 answer ,其中每個 answer[i][j] 是所有滿?下述條件的元素 mat[r][c] 的和:
? i - k <= r <= i + k,
? j - k <= c <= j + k 且
? (r, c) 在矩陣內。
?例 1:
輸?:mat = [[1,2,3],[4,5,6],[7,8,9]], k = 1
輸出:[[12,21,16],[27,45,33],[24,39,28]]
?例 2:
輸?:mat = [[1,2,3],[4,5,6],[7,8,9]], k = 2
輸出:[[45,45,45],[45,45,45],[45,45,45]]
提?:
m = = mat.length
n = = mat[i].length
1 <= m, n, k <= 100
1 <= mat[i][j] <= 100
解法:
算法思路:
?維前綴和的簡單應?題,關鍵就是我們在填寫結果矩陣的時候,要找到原矩陣對應區域的「左上?」以及「右下?」的坐標(推薦?家畫圖)
左上?坐標: x1 = i - k,y1 = j - k ,但是由于會「超過矩陣」的范圍,因此需要對 0
取?個 max 。因此修正后的坐標為: x1 = max(0, i - k), y1 = max(0, j - k) ;
右下?坐標: x1 = i + k,y1 = j + k ,但是由于會「超過矩陣」的范圍,因此需要對 m
- 1 ,以及 n - 1 取?個 min 。因此修正后的坐標為: x2 = min(m - 1, i + k),
y2 = min(n - 1, j + k) 。
然后將求出來的坐標代?到「?維前綴和矩陣」的計算公式上即可~(但是要注意下標的映射關系)

代碼
Java 算法代碼:
class Solution {public int[][] matrixBlockSum(int[][] mat, int k) {int m = mat.length, n = mat[0].length;// 1. 預處理前綴和矩陣int[][] dp = new int[m + 1][n + 1];//方便處理邊界情況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[i][j]// 2. 使?int[][] ret = new int[m][n];for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){int x1 = Math.max(0, i - k) + 1, y1 = Math.max(0, j - k) + 1;int x2 = Math.min(m - 1, i + k) + 1, y2 = Math.min(n - 1, j + k) + 1;ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];}return ret;}
}
C++ 算法代碼:
class Solution {
public:vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {int m = mat.size(), n = mat[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1));// 1. 預處理前綴和矩陣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];// 2. 使?vector<vector<int>> ret(m, vector<int>(n));for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){int x1 = max(0, i - k) + 1, y1 = max(0, j - k) + 1;int x2 = min(m - 1, i + k) + 1, y2 = min(n - 1, j + k) + 1;ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];}return ret;}
};