661. 图片平滑器 :「模拟」&「前缀和」

简介: 661. 图片平滑器 :「模拟」&「前缀和」

网络异常,图片无法展示
|


题目描述



这是 LeetCode 上的 661. 图片平滑器 ,难度为 简单


Tag : 「模拟」、「前缀和」


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


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


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


网络异常,图片无法展示
|


给你一个表示图像灰度的 m * nmn 整数矩阵 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.lengthm==img.length
  • n == img[i].lengthn==img[i].length
  • 1 <= m, n <= 2001<=m,n<=200
  • 0 <= img[i][j] <= 2550<=img[i][j]<=255


朴素解法



为了方便,我们称每个单元格及其八连通方向单元格所组成的连通块为一个 item


数据范围只有 200200,我们可以直接对每个 item 进行遍历模拟。


代码:


class Solution {
    public int[][] imageSmoother(int[][] img) {
        int m = img.length, n = img[0].length;
        int[][] ans = new int[m][n];
        int[][] dirs = new int[][]{{0,0},{1,0},{-1,0},{0,1},{0,-1},{-1,-1},{-1,1},{1,-1},{1,1}};
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                int tot = 0, cnt = 0;
                for (int[] di : dirs) {
                    int nx = i + di[0], ny = j + di[1];
                    if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
                    tot += img[nx][ny]; cnt++;
                }
                ans[i][j] = tot / cnt;
            }
        }
        return ans;
    }
}
复制代码


class Solution:
    def imageSmoother(self, img: List[List[int]]) -> List[List[int]]:
        m, n = len(img), len(img[0])
        dirs = [[i, j] for i in range(-1, 2) for j in range(-1, 2)]
        ans = [[0] * n for _ in range(m)]
        for i in range(m):
            for j in range(n):
                tot, cnt = 0, 0
                for di in dirs:
                    nx, ny = i + di[0], j + di[1]
                    if nx < 0 or nx >= m or ny < 0 or ny >= n:
                        continue
                    tot += img[nx][ny]
                    cnt += 1
                ans[i][j] = tot // cnt
        return ans
复制代码


  • 时间复杂度:O(m * n * C)O(mnC),其中 CC 为灰度单位所包含的单元格数量,固定为 99
  • 空间复杂度:O(m * n)O(mn)


前缀和



在朴素解法中,对于每个 ans[i][j]ans[i][j] 我们都不可避免的遍历 88 联通方向,而利用「前缀和」我们可以对该操作进行优化。


对于某个 ans[i][j]ans[i][j] 而言,我们可以直接计算出其所在 item 的左上角 (a, b) = (i - 1, j - 1)(a,b)=(i1,j1) 以及其右下角 (c, d) = (i + 1, j + 1)(c,d)=(i+1,j+1),同时为了防止超出原矩阵,我们需要将 (a, b)(a,b)(c, d)(c,d) 对边界分别取 maxmin


当有了合法的 (a, b)(a,b)(c, d)(c,d) 后,我们可以直接计算出 item 的单元格数量(所包含的行列乘积)及 item 的单元格之和(前缀和查询),从而算得 ans[i][j]ans[i][j]


代码:


class Solution {
    public int[][] imageSmoother(int[][] img) {
        int m = img.length, n = img[0].length;
        int[][] sum = new int[m + 10][n + 10];
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + img[i - 1][j - 1];
            }
        }
        int[][] ans = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                int a = Math.max(0, i - 1), b = Math.max(0, j - 1);
                int c = Math.min(m - 1, i + 1), d = Math.min(n - 1, j + 1);
                int cnt = (c - a + 1) * (d - b + 1);
                int tot = sum[c + 1][d + 1] - sum[a][d + 1] - sum[c + 1][b] + sum[a][b];
                ans[i][j] = tot / cnt;
            }
        }
        return ans;
    }
}
复制代码


class Solution:
    def imageSmoother(self, img: List[List[int]]) -> List[List[int]]:
        m, n = len(img), len(img[0])
        sum = [[0] * (n + 10) for _ in range(m + 10)]
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + img[i - 1][j - 1]
        ans = [[0] * n for _ in range(m)]
        for i in range(m):
            for j in range(n):
                a, b = max(0, i - 1), max(0, j - 1)
                c, d = min(m - 1, i + 1), min(n - 1, j + 1)
                cnt = (c - a + 1) * (d - b + 1)
                tot = sum[c + 1][d + 1] - sum[a][d + 1] - sum[c + 1][b] + sum[a][b]
                ans[i][j] = tot // cnt
        return ans
复制代码


  • 时间复杂度:O(m * n)O(mn)
  • 空间复杂度:O(m * n)O(mn)


同类型加餐



今日份加餐:【面试高频题】难度 1.5/5,一道「桶排序 + 前缀和」优化题 🎉 🎉


最后



这是我们「刷穿 LeetCode」系列文章的第 No.661 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先将所有不带锁的题目刷完。


在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。


为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…


在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

相关文章
|
存储 移动开发 算法
前缀和算法练习集
前缀和算法练习集
266 0
|
4天前
|
缓存 人工智能 安全
GPT-5.6 Terra与GPT-5.5性能实测:成本减半后的跑分对比与快速迁移指南
GPT-5.6 Terra 的定价为每百万 token 输入 2.50/输出 15。GPT-5.5 则是 5/ 30。Terra 的每一项费率,包括 $0.25/M 的缓存读取,都恰好是 GPT-5.5 的一半,因此在任何工作负载组合下,Terra 都固定 便宜 2.0x。以每天 10 万次请求、3K token 提示词计算,大约是 Terra 每天 2,000,GPT−5.5每天 4,000,即每月约 60,000对 120,000。问题在于:OpenAI 没有发布任何针对 Terra 的编码基准。那个著名的 91.9% Terminal-Bench 数字是 Sol 在 Ul
|
3天前
|
SQL 人工智能 自然语言处理
大模型内容安全实时防护:恶意Prompt注入拦截、越权阻断与熔断机制方案.166
本文系统阐述大模型输入安全防护体系,涵盖提示词注入、恶意Prompt拦截、越权阻断与输入熔断四大核心风险及应对方案。提出四层防护架构(预处理、检测、鉴权、熔断),结合规则引擎、语义识别与RBAC权限控制,实现全链路实时防护,保障业务合规、数据安全与服务稳定。
230 1
|
27天前
|
Linux 程序员 数据格式
【2026最新】Notepad++下载、安装和使用一篇搞定(附中文版安装包)
Notepad++ 是一款免费开源、轻量高效的 Windows 文本编辑器,支持 C/Python/HTML 等 80+ 语言语法高亮、代码折叠、正则替换、编码转换及插件扩展,专为程序员与文本处理用户打造,完美替代系统记事本。(239字)
|
4天前
|
存储 人工智能 JSON
Qwen 本地部署搭配 ComfyUI 生成 AI 漫剧完整实操指南(小白零基础可落地,零成本无限生成+角色一致性天花板)
2026全网最优本地漫剧流水线:零成本、离线运行、角色统一、低配(8G显卡)可跑。融合Qwen本地大模型+ComfyUI双引擎,实现剧本生成→分镜绘图→动态成片全自动,隐私安全、无审核限流,新手30分钟上手,日更无忧。(239字)
|
11天前
|
人工智能 编解码 物联网
2026 最新Stable Diffusion 本地部署教程 下载安装使用详细图解(含官网安装包)
Stable Diffusion(SD)是2022年发布的开源文生图模型,由Stability AI等联合开发。支持文生图、图生图、局部重绘等,依托VAE降低算力需求,可在消费级显卡运行。本文提供秋葉aaaki制作的Windows整合包(含图形界面与插件),开箱即用,零配置启动。
|
4天前
|
人工智能 缓存 JSON
刚刚 GPT-5.6 发布,吊打 Claude 5 和 Grok 4.5?一手实测来啦!
GPT-5.6 刚发布,跑分号称超越 Fable 5,真的假的?附一手实测,让 3 个最强 AI 编程模型 GPT-5.6 Sol、Claude Fable 5、Grok 4.5 在 Cursor 里同时一把梭开发网页游戏,看看最新模型到底谁更能打。
281 0
|
21天前
|
存储 人工智能 监控
QoderWork完全指南:从入门到精通,把“AI实习生”变成你的全能工作搭档
阿里云2026年推出的桌面端AI工作助手QoderWork,不止聊天,更可动手干活:本地运行、安全可控,支持文件整理、数据分析、PPT生成、网页开发等;内置专家套件、多Agent协作与自定义Skills,让AI真正成为你身边的“AI实习生”。