算法33.0

1314. 矩阵区域和 - 力扣(LeetCode)


自己的理解:

算题的时候 计算二维数组的和的时候 第一反应是按照自己的方式 并没有联想到之前学习过二维前缀和的内容 必要且及时的复习

如何快速的得出二维数组的前缀和公式:

提示:两个图片能否勾起算法27.0 里面的解析

分为如何求 dp[ i ][ j ] 以及如何使用前缀和数组 这两个图片一个对应一个

dp[][]是要注意面积的拆分 使用是要注意明确好区间之后 大面积减去小面积

如何计算answer某一个位置的数?

首先这里的k并不是固定的等于1 所以这个绿框框的范围是根据k的大小而改变的

如何确定这个范围呢? 受到使用二维前缀和数组那里的启示 其实是要确定左上角和右下角的坐标 确定好了之后 这个范围就确定了 再把这个范围套到mat(arr)上进行计算

注意数组越界异常 因为这个往mat数组上套的时候 有时候一部分是在外面的 外面的这部分元素不需要也获取不到 还会造成数组越界异常 就像下面的情况(k=1)

这个时候要怎么解决?

对于左上角方块 我们需要注意的是补药小于0 而对于右下角方块 我们需要注意的是补药超了mat数组本身

我们可以用函数来解决这个问题 取值

小的不可能小过0 大的不可能大过m-1(边界)

下标的映射关系:?

在之前学习二维前缀和模板的时候 为了避免边界情况的麻烦 我们是默认了dp数组下标从1开始

但是这道题的数组下标是从0开始的 这个时候要怎么解决? 画出来好理解一些:

如果这里有点迷糊的话 从算法27.0推导出来的公式入手

D = dp[ x2 ][ y2 ] - dp[ x1-1 ][ y2 ] - dp[ x2 ][ y1-1 ] 如果x1取0的话 是负1 这里需要处理边界情况

之前的话 我们的arr数组从1开始 我们的dp也是从1开始 (但是现在dp是从0开始 扩充了)

填写dp表(1,1)的时候,我们需要在mat表里面找的是(0,0)

同理 使用dp表的时候 ans也是从0开始计数的 填写ans(0,0)的时候 dp表需要统一加1

.这样太麻烦了 当用到dpi的时候统一加一减一的

更方便的是 在求下标的时候 直接加1

求answer边界的时候 直接在answer上面加1 对应到dp表里面

解释:想象一下 你有一个正常的世界 和 一个带缓冲区的世界

正常的世界是原矩阵 房子编号从0 开始 0 1 2 3 4 ...

带缓冲的世界是dp表 房子编号从0开始 0(缓冲区) 1 2 3 4 ...

之前我们为了避免边界 规定了0号房子是空的缓冲区 从1号开始才对应正常世界的房子

这样设定之后

在正常的世界中 你想要从2号房子到4号房子的朋友:

正常世界:2号到4号 带缓冲的世界:需要找3号到5号(因为1号对应正常世界的0号)

与其每次都在脑子里面转换:正常世界的2号房子对应缓冲世界的3号 正常世界4号对应缓冲5号

不如统一规则:只要从正常的世界去缓冲世界 所有地址自动+1

放到代码里表现就是:

int x1 = Math.max(0,i-k)+1 ,y1=Math.max(0,j-k)+1;

int x2 = Math.min(m-1,i+k)+1 ,y2=Math.min(n-1,j+k)+1;

这样就会简化很多步骤


细节:

审题:这道题目审题比较不容易 其实就是要把握住关键概念 少一点想法多一点现实迭代

本题:answer二维数组和mat二维数组同等规模

这个是审题的关键 : i-k<= r <= i+k j-k <= c <= j+k 带入数字之后-1<= r <= 1 这个 表示的是在mat数组上从-1 到 1 的位置


别人的讲解:

下面是题目、效果图和代码:
java 复制代码
class Solution 
{
    public int[][] matrixBlockSum(int[][] mat, int k) 
    {
        
     //先求一下原矩阵的规模
     int m = mat.length , n = mat[0].length;

     //1.预处理一个前缀和矩阵
     int[][] dp = new int[m+1][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];}

    //2.使用前缀和矩阵
    int[][] ret = new int[m][n]; //同等大小就可以
    for(int i = 0; i<m; i++ )
      for(int j = 0;j<n ; j++)
      {
        int x1 = Math.max(0,i-k)+1,y1=Math.max(0,j-k)+1;
        int x2 = Math.min(m-1,i+k)+1,y2=Math.min(n-1,j+k)+1;
        ret[i][j]=dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1];
      }
    return ret; 
    }
}

//xiyu251113&1#4*8
相关推荐
生成论实验室几秒前
《事件关系阴阳博弈动力学:识势应势之道》第一篇:生成正在发生——从《即事经》到事件-关系网络
人工智能·科技·算法·架构·创业创新
漂流瓶jz5 分钟前
UVA-1152 和为0的4个值 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·二分查找·题解·aoapc·算法竞赛入门经典·uva
leoufung13 分钟前
LeetCode 76:Minimum Window Substring 题解与滑动窗口思维详解
算法·leetcode·职场和发展
小O的算法实验室26 分钟前
2026年IEEE TETCI,山区环境下基于双种群进化的协同无人机巡逻任务协同优化,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
生成论实验室1 小时前
《事件关系阴阳博弈动力学:识势应势之道》第二篇:阴阳博弈——认知的动力学基础
数据结构·人工智能·科技·神经网络·算法
风筝在晴天搁浅1 小时前
字节高频题 小于n的最大数
算法
LabVIEW开发1 小时前
LabVIEW水力机组空蚀在线监测
算法·labview·labview知识·labview功能·labview程序
AI科技星1 小时前
科幻艺术书本封面:《全域数学》第一部·数术本源 第三卷 代数原本(P95-141)完整五级目录【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算
风筝在晴天搁浅1 小时前
LeetCode 92.反转链表Ⅱ
算法·leetcode·链表
王老师青少年编程2 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【贪心与二分判定】:数列分段 Section II
c++·算法·贪心·csp·信奥赛·二分判定·数列分段 section ii