661. 图片平滑器(简单)- LeetCode

本文详细解析了矩阵平滑算法的实现过程,通过遍历矩阵每个元素并计算其周围元素的平均值来达到平滑效果。算法适用于图像处理等领域,能够有效减少噪声,提升图像质量。

题目描述

在这里插入图片描述

自己解法

挨个遍历矩阵下标,判定矩阵范围,如果范围合理,则统计个数:

class Solution:
    def imageSmoother(self, M: List[List[int]]) -> List[List[int]]:
        H,W = len(M),len(M[0])
        A = [[0] * W for _ in M]
        for i in range(H):
            for j in range(W):
                count = 0
                for r in (i-1,i,i+1):
                    for m in (j-1,j,j+1):
                        if 0 <= r < H and 0 <= m < W:
                            count += 1
                            A[i][j] += M[r][m]
                A[i][j] = A[i][j] //  count
        return A

在这里插入图片描述

官方解答

与自己解法类似,参考官方解答

### 关于二维前缀和的示例题目及其解法 #### 示例题目:LeetCode 304. 二维区域和检索 - 矩阵不可变 此题要求实现一个数据结构 `NumMatrix`,用于快速计算给定矩形区域内元素的总和。该类应支持初始化时传入整数矩阵 `matrix` 并提供方法 `sumRegion(row1, col1, row2, col2)` 来返回左上角位于 `(row1,col1)` 右下角位于 `(row2,col2)` 的子矩阵内的所有元素之和。 为了高效解决这个问题,可以预先计算并保存每个位置到原点(0,0)之间所有元素构成的矩形区域内的累积和作为辅助工具,在后续调用过程中利用这些已知的结果加速运算过程[^1]。 ```python class NumMatrix: def __init__(self, matrix: List[List[int]]): if not matrix or not matrix[0]: self.sums = None return m, n = len(matrix), len(matrix[0]) self.sums = [[0]*(n+1) for _ in range(m+1)] for i in range(1,m+1): for j in range(1,n+1): self.sums[i][j]=self.sums[i-1][j]+self.sums[i][j-1]-self.sums[i-1][j-1]+matrix[i-1][j-1] def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int: if self.sums is None: return 0 A=self.sums[row2+1][col2+1] B=self.sums[row1][col2+1] C=self.sums[row2+1][col1] D=self.sums[row1][col1] return A-B-C+D # Your NumMatrix object will be instantiated and called as such: # obj = NumMatrix(matrix) # param_1 = obj.sumRegion(row1,col1,row2,col2) ``` 上述代码实现了基于二维前缀和的数据结构,通过提前构建好累加表使得每次查询操作可以在常量时间内完成。具体来说就是先遍历整个输入矩阵一次建立一个新的二维数组用来记录从坐标 (0,0) 到当前坐标的矩形范围内所有数值相加之和;之后每当需要获取任意指定范围内的值的时候只需要做简单的四则运算即可得出结果[^4]。 #### 示例题目:LeetCode 661. 图片平滑器 本题旨在对图像中的每一个像素进行处理得到新的颜色强度值,新值等于它自己以及周围八个方向上的邻居们的平均灰度值(如果某个方向不存在有效邻接点,则忽略)。这里同样可以通过构造二维前缀和的方式来简化边界情况下的判断逻辑,并提高整体性能表现。 ```cpp vector<vector<int>> imageSmoother(vector<vector<int>>& M) { vector<vector<int>> res(M.size(), vector<int>(M[0].size())); // 构建二维前缀和 vector<vector<int>> prefixSum(M.size() + 1, vector<int>(M[0].size() + 1)); for(int i=1; i<=M.size(); ++i){ for(int j=1; j<=M[0].size(); ++j){ prefixSum[i][j] = M[i-1][j-1] + prefixSum[i-1][j] + prefixSum[i][j-1] - prefixSum[i-1][j-1]; } } auto getSum = [&](int r1,int c1,int r2,int c2)->int{ return prefixSum[r2+1][c2+1] - prefixSum[r1][c2+1] - prefixSum[r2+1][c1] + prefixSum[r1][c1]; }; for(size_t i=0;i<M.size();++i){ for(size_t j=0;j<M[0].size();++j){ int cnt = 0; int sr = max((int)i-1,0); int sc = max((int)j-1,0); int er = min(i+1,(int)(M.size()-1)); int ec = min(j+1,(int)(M[0].size()-1)); res[i][j]=(getSum(sr,sc,er,ec)/(pow(er-sr+1,2))); } } return res; } ``` 这段 C++ 实现展示了如何应用二维前缀和技术来优化图片平滑化的过程。首先创建了一个额外的空间存储原始图象经过转换后的前缀和形式;接着定义了帮助函数 `getSum()` 方便提取特定区间内部的所有元素合计;最后按照规则更新目标输出矩阵中对应位置的新亮度值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值