给你一个 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
提示 1
How to calculate the required sum for a cell (i,j) fast ?
提示 2
Use the concept of cumulative sum array.
提示 3
Create a cumulative sum matrix where dp[i][j] is the sum of all cells in the rectangle from (0,0) to (i,j), use inclusion-exclusion idea.
解法:二维前缀和
Java版:
class Solution {
public int[][] matrixBlockSum(int[][] mat, int k) {
int m = mat.length;
int n = mat[0].length;
int[][] presum = new int[m + 1][n + 1];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
presum[i + 1][j + 1] = presum[i + 1][j] + presum[i][j + 1] - presum[i][j] + mat[i][j];
}
}
int[][] ans = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
ans[i][j] = presum[Math.min(i + k + 1, m)][Math.min(j + k + 1, n)] - presum[Math.min(i + k + 1, m)][Math.max(j - k, 0)] - presum[Math.max(i - k, 0)][Math.min(j + k + 1, n)] + presum[Math.max(i - k, 0)][Math.max(j - k, 0)];
}
}
return ans;
}
}
Python3版:
class Solution:
def matrixBlockSum(self, mat: List[List[int]], k: int) -> List[List[int]]:
m = len(mat)
n = len(mat[0])
presum = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(m):
for j in range(n):
presum[i + 1][j + 1] = presum[i + 1][j] + presum[i][j + 1] - presum[i][j] + mat[i][j];
ans = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
ans[i][j] = presum[min(i + k + 1, m)][min(j + k + 1, n)] - presum[min(i + k + 1, m)][max(j - k, 0)] - presum[max(i - k, 0)][min(j + k + 1, n)] + presum[max(i - k, 0)][max(j - k, 0)]
return ans
复杂度分析
- 时间复杂度:O(MN)。
- 空间复杂度:O(MN)。