leetcode 1314. Matrix Block Sum

Given a m * n matrix mat and an integer K, return a matrix answer where each answer[i][j] is the sum of all elements mat[r][c] for i - K <= r <= i + K, j - K <= c <= j + K, and (r, c) is a valid position in the matrix.

 

Example 1:

Input: mat = [[1,2,3],[4,5,6],[7,8,9]], K = 1
Output: [[12,21,16],[27,45,33],[24,39,28]]

Example 2:

Input: mat = [[1,2,3],[4,5,6],[7,8,9]], K = 2
Output: [[45,45,45],[45,45,45],[45,45,45]]

 

Constraints:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n, K <= 100
  • 1 <= mat[i][j] <= 100

题目大意:

给你一个 m * n 的矩阵 mat 和一个整数 K ,请你返回一个矩阵 answer ,其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和: 

  i - K <= r <= i + K, j - K <= c <= j + K 
  (r, c) 在矩阵内。

 

思路:这题其实可以看作对灰度图做均值滤波,滤波器大小为$K \times K$。如果直接计算的话,时间复杂度为$O(m \times n \times K \times K)$。采用动态规划思想,初始化二维矩阵dp,dp[i][j]表示矩阵mat从(0,0)到(i,j)组成的矩阵之和。dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + mat[i][j],同时考虑i=0或者j=0的边界情况。

当计算answer[i][j]时,通常情况下answer[i][j] = dp[i + K][j + K] - dp[i + K][j - K - 1] - dp[i - K - 1][j + K] + dp[i - K - 1][j - K - 1]。同时考虑i + K >= row, j + k >= col, i - K - 1 < 0, j - K - 1 < 0的边界情况就好了。

 1 class Solution {
 2 public:
 3     vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int K) {
 4         int row = mat.size(), col = (row > 0) ? mat[0].size() : 0;
 5         vector<vector<int>> dp(row, vector<int>(col, 0));
 6         dp[0][0] = mat[0][0];
 7         for(int i = 1; i < row; ++i) {
 8             dp[i][0] = dp[i - 1][0] + mat[i][0];
 9         }
10         for (int j = 1; j < col; ++j) {
11             dp[0][j] = dp[0][j - 1] + mat[0][j];
12         }
13         for (int i = 1; i < row; ++i) {
14             for (int j = 1; j < col; ++j) {
15                 dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1] + mat[i][j];
16             }
17         }
18         vector<vector<int>> ans(row, vector<int>(col, 0));
19         for (int i = 0; i < row; ++i) {
20             for (int j = 0; j < col; ++j) {
21                 int left = (j - K - 1) >= 0 ? dp[min(i + K, row - 1)][j - K - 1] : 0;
22                 int top = (i - K - 1) >= 0 ? dp[i - K - 1][min(j + K, col - 1)] : 0;
23                 int topleft = (i - K - 1) >= 0 && (j - K - 1) >= 0 ? dp[i - K - 1][j - K - 1] : 0;
24                 ans[i][j] = dp[min(i + K, row - 1)][min(j + K, col - 1)] - left - top + topleft;
25             }
26         }
27         return ans;
28     }
29 };

时间复杂度:$O(m \times n)$

空间复杂度:$O(m \times n)$

posted @ 2020-06-04 23:00  琴影  阅读(613)  评论(2编辑  收藏  举报