题目
leetcode 1314.矩形区域和
解释:
已知: 矩阵mat,整数k
求解:对于矩阵mat中的一坐标为(i,j)的元素,在矩阵范围内,求从元素(i - k, j - k)到元素(i + k, j + k)的矩形区域内所有值的和。
example: 如下图所示,对于mat[5][5],k = 1,对于元素(i, j),求(i - 1, j - 1)到(i + 1, j + 1)的矩形区域中所有元素和,即下图黑框框住的矩形中所有元素的和。
BF算法
暴力算法思路
遍历mat中所有元素,假设遍历到(i, j),则将限制在mat矩阵范围内的(i - k, j - k)-(i + k, j + k)范围的矩形区域找出,遍历该矩形区域中的元素值并累加得解。
对于矩形区域重点解释:
满足两个条件:
1:不超过mat矩阵范围;因此矩形范围区间: 0 <= row < mat.size(); 0 <= col < mat[0].size();
2:(i - k, j - k)-(i + k, j + k)的矩形区域,即矩形内左上角元素坐标为(i - k, j - k),右下角元素坐标为(i + k, j + k)。则矩形范围区间:i-k <= row <= i+k; j-k <= col <= j+k;
因此,矩形区间的行和列具体范围取决于:左区间的更大的一方,右区间更小的一方
class Solution {
public:
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
int m = mat.size(), n = mat[0].size();
vector<vector<int>> matrix(m, vector(n, 0));
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
int sum = 0;
for(int x = max(i - k, 0); x < min(i + k, m - 1); x++) {
for(int y = max(j - k, 0); y < min(j + k, n - 1); j++)
sum += mat[x][y];
}
matrix[i][j] = sum;
}
}
return matrix;
}
};
动态规划
求状态转移方程
s[I][j]
vector<vector> s(m + 1, vector(n + 1, 0)) (m,n分别为mat的长和宽)
构造更大的范围是更利于计算s,因此mat中的元素在s中需要扩大。
s[I][j]:表示的是以mat[i - 1][j - 1]为右下角的矩形区域的所有值的和
以(i, j)为右下角的矩形区域所有值的和。如图所示
对于mat[I][j],求s[I+1][j+1]
如下图所示
s[I+1][j+1] = 红色矩形区域值 + 绿色矩形区域值 - 黑色虚线框矩形区域值 + mat[i][j]
res[I][j]
res[I][j]:表示矩形区域内所有值的和
res[I][j] = 黑色虚线框部分 - 红色部分 - 绿色部分 + 白色部分
class Solution {
public:
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
int m = mat.size(), n = mat[0].size();
vector<vector<int>> s(m + 1, vector(n + 1, 0));
vector<vector<int>> res(m, vector(n, 0));
//求矩形前缀和,s[i + 1][j + 1]表示的是mat[i][j]的矩形前缀和
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= n; j++)
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + mat[i - 1][j - 1];
}
//求res
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
int xMin = max(0, i - k), yMin = max(0, j - k);
int xMax = min(m - 1, i + k), yMax = min(n - 1, j + k);
res[i][j] = s[xMax + 1][yMax + 1] - s[xMin][yMax + 1] - s[xMax + 1][yMin] + s[xMin][yMin];
}
}
return res;
}
};