Leetcode 661.图片平滑器

原题链接:Leetcode 661. Image Smoother

An image smoother is a filter of the size 3 x 3 that can be applied to each cell of an image by rounding down the average of the cell and the eight surrounding cells (i.e., the average of the nine cells in the blue smoother). If one or more of the surrounding cells of a cell is not present, we do not consider it in the average (i.e., the average of the four cells in the red smoother).

在这里插入图片描述
Given an m x n integer matrix img representing the grayscale of an image, return the image after applying the smoother on each cell of it.

Example 1:
在这里插入图片描述

Input: img = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[0,0,0],[0,0,0],[0,0,0]]
Explanation:
For the points (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0
For the points (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0
For the point (1,1): floor(8/9) = floor(0.88888889) = 0

Example 2:
在这里插入图片描述

Input: img = [[100,200,100],[200,50,200],[100,200,100]]
Output: [[137,141,137],[141,138,141],[137,141,137]]
Explanation:
For the points (0,0), (0,2), (2,0), (2,2): floor((100+200+200+50)/4) = floor(137.5) = 137
For the points (0,1), (1,0), (1,2), (2,1): floor((200+200+50+200+100+100)/6) = floor(141.666667) = 141
For the point (1,1): floor((50+200+200+200+200+100+100+100+100)/9) = floor(138.888889) = 138

Constraints:

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

题目大意:

有一个 m x n 的矩阵 img ,定义 img[i][j] 的平均值是以 img[i][j] 为中心的九宫格的值的平均值。
img[i][j] 周围的格子不能构成九宫格时,有多少就按多少来算平均值。
最后以二维数组的形式返回矩阵 img 的平均值

方法一:模拟

思路:

m、n的最大值是200,也就是说矩阵的最高规模是200 x 200
可以直接模拟,挨个求平均值

C++ 代码:

class Solution {
public:
    vector<vector<int>> imageSmoother(vector<vector<int>>& img) {
        // m行 n列
        int m = img.size(), n = img[0].size();

        // 初始化结果数组ans
        vector<vector<int>> ans(m, vector<int>(n));

        for(int i = 0; i < m; i++ ){
            for(int j = 0; j < n; j++ ){
                // sum总和 num是组成对应item的个数
                int sum = 0, num = 0;

                // xy为偏移量
                for(int x = - 1; x <= 1; x++ ){
                    for(int y = -1; y <= 1; y++ ){
                        if(i + x >= 0 && i + x < m && j + y >= 0 && j + y < n){
                            num++;
                            sum += img[i + x][j + y];
                        }
                    }
                }

                ans[i][j] = sum / num;
            }
        }

        return ans;
    }
};

复杂度分析;

  • 时间复杂度:O(mn),两重循环遍历每个cell,对于每个cell的计算是不超过9个值求平均值。
  • 空间复杂度:O(1)

方法二:二维前缀和

c++代码:

class Solution {
public:
    vector<vector<int>> imageSmoother(vector<vector<int>>& img) {
        // m行号 n列号
        int m = img.size();
        int n = img[0].size();

        // 定义前缀和数组
        vector<vector<int>> pre(m+1, vector<int>(n+1, 0));
        
        // 预处理 下标从1开始
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                pre[i][j] = pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + img[i-1][j-1];
            }
        }

        // 结果数组
        vector<vector<int>> ans(m, vector<int>(n, 0));

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                // 确定范围
                int left = max(j-1, 0);
                int right = min(j+1, n-1);
                int top = max(i-1, 0);
                int bottom = min(i+1, m-1);

                int cnt = (bottom - top + 1) * (right - left + 1);
                int sum = pre[bottom+1][right+1] - pre[top][right+1] - pre[bottom+1][left] + pre[top][left];

                ans[i][j] = sum / cnt;
            }
        }

        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值