标题:1314. 矩阵区域和
难度:中等
天数:第14天,第1/2题
给你一个
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
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
//动态规划 第 14 天 1/2
public int[][] matrixBlockSum(int[][] mat, int k) {
int m = mat.length;
int n = mat[0].length;
//dp[i][j]储存的是,[0,0]到[i,j]为右下角矩形内元素的和
//并且第一横排和第一竖排全部赋值0
int[][] dp = new int[m+1][n+1];
for(int i = 0 ; i < m;i++){
for(int j = 0 ; j < n;j++){
//0, 0, 0, 0
//0 [i-1,j-1] [i-1,j] [i-1,j+1]
//0 [ i ,j-1] [ i ,j] [ i ,j+1]
//0 [i+1,j-1] [i+1,j] [i+1,j+1]
//dp相当于从[1,1]开始记录值,所以dp[i+1][j+1] +mat[i][j]对应的值
dp[i+1][j+1] = dp[i+1][j] + dp[i][j+1] - dp[i][j] + mat[i][j];
}
}
for(int i = 0 ; i < m;i++){
for(int j = 0 ; j < n;j++){
//左上角 竖排的值min(m,n)里的m
int topM = Math.max(0, i - k);
//左上角 横排的值min(m,n)里的n
int topN = Math.max(0, j - k);
//右下角 竖排的值 max(m,n)里的m
int bottomM = Math.min(m-1, i + k) + 1;
//右下角 横排的值 max(m,n)里的n
int bottomN = Math.min(n-1, j + k) + 1;
//0, 0, ... 0, ... 0
//0 [i-k,j-k] ... [i-k,j] [i-k,j+k]
// ... ... ...
//0 [ i ,j-k] ... [ i ,j] ... [ i ,j+k]
// ... ... ...
//0 [i+k,j-k] ... [i+k,j] ... [i+k,j+k]
//dp[bottomM][bottomN] = dp[i+k][j+k] 最大面积值
//- dp[topM][bottomN] = dp[i-k][j+k] 减去最上边一条
//- dp[bottomM][topN] = dp[i+k][j-k] 减去最左边一条
//+ dp[topM][topN] = dp[i-k][j-k] 加上多减去一次的[i-k,j-k]
//并给元数组赋值,减少空间使用
mat[i][j] = dp[bottomM][bottomN] - dp[topM][bottomN] - dp[bottomM][topN] + dp[topM][topN];
}
}
return mat;
}
}