题目
给你一个 m * 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)
链接:https://leetcode-cn.com/problems/matrix-block-sum
分析
看了一下,这是一道二维的前缀和的题目,有点像二维积分.也没做过二维的前缀和,做一下看看
首先确定一下二维数组sum[i][j]的含义,sum[x][y]是从sum{i,j} 0<=i<=x,0<=j<=y,就是它前面的所有元素的和,和一维的前缀和多出一个sum[0]=0,这个数组的第一行和第一列都是0,保证从0开始的能够计算,所以sum数组是[row+1][col+1]大小的,计算中有两个地方注意
-
在计算sum数组时
因为mat数组和sum数组不是对齐的,mat[i-1][j-1]对齐sum[i][j],计算时就是先把左和上相加,要去掉重复的部分(sum[i-1][j-1]),之后加上自己(mat[i][j]),画个图对应一下就清楚了 -
在计算答案时
计算的时候首先关注越界,使用max,min对索引进行约束,计算时,减去左和上,减去的部分有重复的(sum[x_bottom][y_bottom]),再加上就得到想要的了(记得mat和sum不对齐,所以x_top和y_top要+1)
代码
//12ms
//9.2MB
class Solution {
public:
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int K) {
int m=mat.size(),n=mat[0].size();
vector<vector<int>> sum(m+1,vector<int>(n+1,0));
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
sum[i][j]=sum[i-1][j]+sum[i][j-1]+mat[i-1][j-1]-sum[i-1][j-1];
}
}
vector<vector<int>> ans(m,vector<int>(n,0));
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
int x_top=min(i+K+1,m),y_top=min(j+K+1,n),x_bottom=max(0,i-K),y_bottom=max(0,j-K);
ans[i][j]=sum[x_top][y_top]-sum[x_bottom][y_top]-sum[x_top][y_bottom]+sum[x_bottom][y_bottom];
}
}
return ans;
}
};