前缀和——1314. 矩阵区域和

文章目录

    • [🎤1. 题目](#🎤1. 题目)
    • [🎤2. 算法原理](#🎤2. 算法原理)
    • [🎤3. 代码实现](#🎤3. 代码实现)

🎤1. 题目

题目链接:1314. 矩阵区域和 - 力扣(LeetCode)

给你一个 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

🎤2. 算法原理

这题的意思就是给我们一个mat矩阵,然后我们返回一个ans矩阵,ans矩阵和mat同等规模,以当前位置为圆心,k为半径,辐射所有元素的和,如下图示例:

这里其实就是一个求二维前缀和 的操作,不了解的可以看一下此篇文章:前缀和------DP35 【模板】二维前缀和

++初始化前缀和矩阵:++

不需要硬记模板,要用的时候,画一个草图,直接推一下就好了

dp[i][i] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + mat[i][j]

++使用前缀和矩阵:++

我们要求的最终结果也是,画一个草图,直接推出来

ans = dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]

当我们要ans[i][j]这个位置的值的时候,需要找到对应的矩阵。

由于是向四周延申,我们只需要左上角和右下角的坐标即可,即(i-k(j-k)(i+k)(j+k)

边界处理:在找左上角和右下角坐标的时候,可能会发生越界,这里我们需要处理一下。

假设左上角坐标为(x1,y1),那么x1 = max(0,i-k)y1 = max(0,j-k)

右下角坐标为(x2,y2),那么x2 = min(m-1,i+k)y2 = min(n-1,j+k)

++下标映射关系:++

我们上面这个DP【35】二位前缀和模板 这题,下标其实是从(1,1)开始的,而本题是从(0,0)开始的。

所以我们填dp表的时候可以多加一行一列,便于我们处理

那么这里的dp公式需要稍微修改一下:dp[i][i] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + mat[i-1][j-1]

要填ans去使用这个dp表的时候,下标统一+1,我们可以直接在求下标的时候+1

x1 = max(0,i-k)+1,y1 = max(0,j-k)+1x2 = min(m-1,i+k)+1y2 = min(n-1,j+k)+1

🎤3. 代码实现

cpp 复制代码
class Solution {
public:
    vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
        int m = mat.size(),n = mat[0].size();

        vector<vector<int>> dp(m+1,vector<int>(n+1));
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
                dp[i][j] = dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+mat[i-1][j-1];
        }
        vector<vector<int>> ans(m,vector<int>(n));
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                int x1 = max(0,i-k)+1, y1=max(0,j-k)+1;
                int x2 = min(m-1,i+k)+1, y2=min(n-1,j+k)+1;
                ans[i][j]=dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1];
            }
        }
        return ans;
    }
};

运行结果:

相关推荐
a诠释淡然6 小时前
C++模板元编程—现代C++的黑魔法
开发语言·c++
汉克老师6 小时前
GESP2026年3月认证C++六级真题与解析(单选题1-8)
c++·多态··构造函数·循环队列·bst·gesp6级
charlie1145141916 小时前
现代C++工程:constexpr 基础:编译期求值的艺术
开发语言·c++
小欣加油7 小时前
leetcode121买卖股票的最佳时机
数据结构·c++·算法·leetcode·职场和发展
牛油果子哥q7 小时前
【C++运算符重载】C++运算符重载终极精讲:单目/双目/关系/赋值运算符重载、成员与全局重载、重载禁区、底层原理与企业级工程规范
开发语言·c++
2601_961845157 小时前
2026四级作文预测题|英语四级写作押题+提纲PDF
java·c语言·数据库·c++·python·pdf·php
郝亚军7 小时前
Visual Studio 2022项目中的.sln是什么?
c++·c#·visual studio
暖阳华笺7 小时前
【高频考点】K-Means聚类算法
c++·算法·机器学习·kmeans·聚类
apcipot_rain7 小时前
计科八股20260609——10分钟速通《线性代数》,知识点极简版
人工智能·线性代数·机器学习
j7~7 小时前
【C++】模板初阶--函数模板,类模板详解
数据结构·c++·算法·函数模板·类模板·函数模板实例化