矩阵操作之:方向向量法

包含整数的二维矩阵 M 表示一个图片的灰度。你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) ,平均灰度的计算是周围的8个单元和它本身的值求平均,如果周围的单元格不足八个,则尽可能多的利用它们。

输入:
[[1,1,1],
 [1,0,1],
 [1,1,1]]
输出:
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]

看到这个题目一开始没啥思路,只有暴力的想法。后来看到别人的思路发现非常神奇,涨姿势了。

首先可以用到的就是方向向量法。把需要操作的格子做成一个方向向量表,遍历向量表操作,同时加上筛选条件,选取需要的格子。代码如下:

class Solution {
    public int[][] imageSmoother(int[][] M) {//方向向量法
        int r = M.length;
        int c = M[0].length;
        int[][] dir = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,0},{0,1},{1,-1},{1,0},{1,1}};
        int[][] res = new int[r][c];
        for(int i = 0; i< r; i++)
            for(int j = 0; j< c; j++)
            {
                int sum = 0;
                int count = 0;
                for(int[] d : dir)
                {
                    int x = i +d[0];
                    int y = j +d[1];
                    if(x < 0 || x >= r || y < 0 || y >= c) continue;
                    sum += M[x][y];
                    count++;
                }
                res[i][j] = sum/count;
            }
        return res;
    }
}

 

看到大家的讨论,还有一种比较简单的方式,那就是小区域法。

最终我需要求和的只是一片矩阵小区域,所以可以把小区域的边界找出来。然后再遍历小区域里面的所有格子。代码如下。

class Solution {
    public int[][] imageSmoother(int[][] M) {//小区域法
        int r = M.length;
        int c = M[0].length;
        int[][] res = new int[r][c];
        for(int i = 0; i< r; i++)
            for(int j = 0; j< c; j++)
            {
                int pu = i-1 < 0 ? i : i-1;
                int pd = i+1 >=r ? i : i+1;
                int pl = j-1 < 0 ? j : j-1;
                int pr = j+1 >=c ? j : j+1;
                int sum = 0;
                for(int x = pu ; x<= pd; x++)
                    for(int y = pl; y<= pr; y++ )
                    sum += M[x][y];
            res[i][j] = sum/((pd-pu+1)*(pr-pl+1));
            }
            return res;
    }
}

不过,总的来说,方向向量会更灵活一点,哪些格子可以任意选取,不一定要矩形。

 

你可能感兴趣的:(LeetCode)