Leetcode每日一题 661. 图片平滑器 二维前缀和公式以及矩阵边界问题

📖本篇内容:Leetcode每日一题 661. 图片平滑器 前缀和公式以及矩阵边界问题

📑 文章专栏:leetcode每日一题《打卡日常》

📆 最近更新:2022 年 3 月 23日 Leetcode每日一题 440. 字典序的第K小数字 无树似有树 学习解题思路(感谢 杨兴元 uu 和 Benhao总)

⭐算法仓库:小付的算法之路——Alascanfu-algorithm.git.io

🙊个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)

🌇 点赞 👍 收藏 ⭐留言 📝 一键三连 关爱程序猿,从你我做起

🙊写在前面🙊

今天是一道二维前缀和与矩阵边界组合问题,其实很容易想到二维前缀和公式求解,但是不会Coding又是另一回事

题目

图像平滑器 是大小为 3 x 3 的过滤器,用于对图像的每个单元格平滑处理,平滑处理后单元格的值为该单元格的平均灰度。

每个单元格的 平均灰度 定义为:该单元格自身及其周围的 8 个单元格的平均值,结果需向下取整。(即,需要计算蓝色平滑器中 9 个单元格的平均值)。

如果一个单元格周围存在单元格缺失的情况,则计算平均灰度时不考虑缺失的单元格(即,需要计算红色平滑器中 4 个单元格的平均值)。

在这里插入图片描述
(给你一个表示图像灰度的 m x n 整数矩阵 img ,返回对图像的每个单元格平滑处理后的图像 。)

示例1:
在这里插入图片描述

输入:img = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[0, 0, 0],[0, 0, 0], [0, 0, 0]]
解释:
对于点 (0,0), (0,2), (2,0), (2,2): 平均(3/4) = 平均(0.75) = 0
对于点 (0,1), (1,0), (1,2), (2,1): 平均(5/6) = 平均(0.83333333) = 0
对于点 (1,1): 平均(8/9) = 平均(0.88888889) = 0

示例2:
在这里插入图片描述

输入: img = [[100,200,100],[200,50,200],[100,200,100]]
输出: [[137,141,137],[141,138,141],[137,141,137]]
解释:
对于点 (0,0), (0,2), (2,0), (2,2): floor((100+200+200+50)/4) = floor(137.5) = 137
对于点 (0,1), (1,0), (1,2), (2,1): floor((200+200+50+200+100+100)/6) = floor(141.666667) = 141
对于点 (1,1): floor((50+200+200+200+200+100+100+100+100)/9) = floor(138.888889) = 138

提示

m == img.length
n == img[i].length
1 <= m, n <= 200
0 <= img[i][j] <= 255

📝思路📝

本题考查知识点

  • 思路:看到这种给定区间的二维矩阵求和问题一般都会想到二维前缀和公式进行求解,本题难点不只是这个二维前缀和公式的考察,同时也考察了矩阵边界的问题处理方式,这里咱们利用图来进行求解,会更直观明了一点。图示之前我们先来理解题意,确立矩阵区间位置,也就是说需要求取哪个子矩阵的和

在这里插入图片描述

根据上图大概就可以知道二维的前缀和公式

二维前缀和公式:

S [ i ] [ j ] = s [ i − 1 ] [ j ] + S [ i ] [ j − 1 ] − S [ i − 1 ] [ j − 1 ] + a [ i ] [ j ] S[i][j] = s[i-1][j] + S[i][j-1] - S[i-1][j-1] + a[i][j] S[i][j]=s[i1][j]+S[i][j1]S[i1][j1]+a[i][j]

其中S[i] [j] 表示第 i 行 j 列组成的矩阵的前缀和

那么获得得到这个前缀和之后有啥用呢? 这就是用来求一个子矩阵的区间和的快速求解方式。
在这里插入图片描述

所以求矩阵区间和公式:

S x 2 y 2 − S x 1 − 1 y 2 − S x 2 y 1 − 1 + S x 1 − 1 y 1 − 1 S_{x_2y_2} - S_{{x_{1-1}}{y_2}} - S_{{x_{2}}{y_{1-1}}} + S_{{x_{1-1}{y_{1-1}}}} Sx2y2Sx11y2Sx2y11+Sx11y11
然后就是边界问题了。

  • 需要注意的是我们针对每个点,需要考虑当前节点是否有左节点 、上节点、下节点 、右节点,且不能跨界。如果跨界就用边界计算 且不统计个数。

⭐代码实现⭐

前缀和求解

class Solution {
    public int[][] imageSmoother(int[][] img) {
        int m = img.length;
        int n = img[0].length;
        int[][] s = new int[m+1][n+1];

        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]+img[i-1][j-1];
            }
        }

        int [][] res = new int[m][n];
        for (int i = 0;i<m;i++){
            for (int j = 0 ; j<n;j++){
                int left = Math.max(0,j-1);
                int right = Math.min(n-1,j+1);

                int top = Math.max(0,i-1);
                int down = Math.min(m-1,i+1);
                int cnt = (right - left + 1) * (down - top + 1);
                int val = s[down+1][right+1] - s[top][right+1] - s[down+1][left] + s[top][left];
                res[i][j] =  val / cnt; 
            }
        }
        return res;
    }

}

运行结果

前缀和

在这里插入图片描述

🙊写在最后🙊

2022- 3 - 24今天小付打卡了哦~

美好的日出 美好的山河

都因有你存在 而璀璨 耀眼

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alascanfu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值