给你一个 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
思路:
该题目是 304. 二维区域和检索 - 矩阵不可变 - 力扣(Leetcode)的变体,我们仍然先计算出 矩阵前缀和,即(0, 0) 到 (i, j) 的矩阵和
c++
class Solution {
public:
vector<vector<int>> preMatSum; // 前缀和
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
int row = mat.size();
int col = mat[0].size();
preMatSum = vector<vector<int>>(row, vector<int>(col, 0));
for(int i=0; i<row; i++) {
if(i == 0) {
preMatSum[i][0] = mat[i][0];
} else {
preMatSum[i][0] = preMatSum[i-1][0] + mat[i][0];
}
}
for(int j=0; j<col; j++) {
if(j == 0) {
preMatSum[0][j] = mat[0][j];
} else {
preMatSum[0][j] = mat[0][j] + preMatSum[0][j-1];
}
}
for(int i=1; i<row; i++) {
for(int j=1; j<col; j++) {
preMatSum[i][j] = mat[i][j] + preMatSum[i-1][j] + preMatSum[i][j-1] - preMatSum[i-1][j-1];
}
}
// for(int i=0; i<row; i++) {
// for(int j=0; j<col; j++) {
// cout<< preMatSum[i][j] <<" ";
// }
// cout<<endl;
// }
vector<vector<int>> result(row, vector<int>(col, 0));
for(int i=0; i<row; i++) {
for(int j=0; j<col; j++) {
int row1 = (i - k) < 0 ? 0 : (i - k);
int col1 = (j - k) < 0 ? 0 : (j - k);
int row2 = (i + k) >= row ? (row - 1):(i + k);
int col2 = (j + k) >= col ? (col - 1):(j + k);
if(row1 == 0 && col1 == 0) {
result[i][j] = preMatSum[row2][col2];
} else if(row1 == 0 && col1 != 0) {
result[i][j] = preMatSum[row2][col2] - preMatSum[row2][col1-1];
} else if(row1 != 0 && col1 == 0) {
result[i][j] = preMatSum[row2][col2] - preMatSum[row1-1][col2];
} else {
result[i][j] = preMatSum[row2][col2] - preMatSum[row2][col1-1] - preMatSum[row1-1][col2] + preMatSum[row1-1][col1-1];
}
}
}
return result;
}
};