LeetCode-Easy部分-图像平滑器

来源:互联网 发布:mysql 数据加密 编辑:程序博客网 时间:2024/06/05 07:17

题目描述:

Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surrounding cells and itself. If a cell has less than 8 surrounding cells, then use as many as you can.

Example 1:

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

Note:

  1. The value in the given matrix is in the range of [0, 255].
  2. The length and width of the given matrix are in the range of [1, 150].
给定一个二维矩阵,输出矩阵的每个元素值为原矩阵围绕它的8个点以及它自己的平均值。如果不够8个点,则包含围绕它的尽可能多的点。

例如,输入

[[1,1,1], [1,0,1], [1,1,1]]

输出矩阵的第一个点的值为点[0,0] [0,1], [1,0] [1,1] 的均值=3/4=0。

最简单的解题思路:遍历这个二维数组,每个元素都判断一下左边,右边,上边,下边是否有元素,再判断左下、左上、右下、右上是否有元素。有的话就加起来,并计数器加一,记得将这个元素也要算入到均值中

 非常简单,但是比较长。

public int[][] imageSmoother(int[][] M) {        int[][] result=new int[M.length][M[0].length];        for(int i=0;i<M.length;i++){            for(int j=0;j<M[0].length;j++){                int sum=M[i][j];                int count=1;                boolean hasLeft=false;                boolean hasRight=false;                boolean hasDown=false;                boolean hasUp=false;                if(i-1>=0){                    sum+=M[i-1][j];                    count++;                              hasLeft=true;                }                if(i+1<M.length){                     sum+=M[i+1][j];                     count++;                     hasRight=true;                }                if(j-1>=0){                    sum+=M[i][j-1];                    count++;                     hasDown=true;                }                if(j+1<M[0].length){                    sum+=M[i][j+1];                    count++;                    hasUp=true;                }                if(hasLeft){                    if(hasDown){                    sum+=M[i-1][j-1];                    count++;                     }                    if(hasUp){                    sum+=M[i-1][j+1];                    count++;                     }                }                if(hasRight){                  if(hasDown){                    sum+=M[i+1][j-1];                    count++;                     }                    if(hasUp){                    sum+=M[i+1][j+1];                    count++;                     }                }                result[i][j]=sum/count;            }                   }        return result;    }

下面还是分析一下LeetCode上的优秀代码,虽然不知道这个大神是谁,但是下面的代码真的是越看越喜欢~

我们在计算每个平均值时其实也是在求一个矩阵的平均值。

这个矩阵就是以这个元素为中心的矩阵的均值。

例如:求第一个元素的围绕的平均值时,其实就是再 求下面红色这个矩阵的平均值:

[[1, 1, 1],
 [1, 0, 1],
 [1, 1, 1]]

第二个元素,对应的矩阵

[[1, 1, 1],
 [1, 0, 1],
 [1, 1, 1]]

最中间的元素,对应的矩阵:

[[1, 1, 1],
 [1, 0,],
 [1, 1, 1]]

所以只要找到每个元素对应的矩阵,然后求这个矩阵的平均值就可以了。

在找这个矩阵时,神秘大神用了一个非常赞的办法,就是把边界限制不超过长度,不小于0。代码如下:

class Solution {    public int[][] imageSmoother(int[][] M) {        int m = M.length;        int n = M[0].length;        int[][] res = new int[m][n];                for (int i = 0; i < m; i++) {            for (int j = 0; j < n; j++) {                res[i][j] = smooth(M, m, n, i, j);            }        }        return res;    }        private int smooth(int[][] M, int m, int n, int x, int y) {        int sum = 0;        int cnt = 0;        for (int i = Math.max(0, x - 1); i <= Math.min(m - 1, x + 1); i++) {            for (int j = Math.max(0, y - 1); j <= Math.min(n - 1, y + 1); j++) {                sum += M[i][j];                cnt++;            }        }        return sum / cnt;    }}

所以要善于用数学函数么!



原创粉丝点击