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

示例 1:

输入:
[[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

注意:

  1. 给定矩阵中的整数范围为 [0, 255]。
  2. 矩阵的长和宽的范围均为 [1, 150]。

分析:
先读懂题,(0,0), (0,2), (2,0), (2,2) 周围包括自己总共四个点,所以当前总和除 4,(0,1), (1,0), (1,2), (2,1)周围包括自己总共 6 个点,所以当前总和除 6,(1,1) 同理
说来是蛮简单的,就是考虑当前值的周围一圈加自己求和除以个数,但是有点麻烦的是,
1. 如何把周围一圈的加自己的遍历写成循环
2. 如何判断该点是否在矩阵内
对于问题 1:
设置两个数组

int xxx[] = { -1, -1, -1, 0, 1, 1, 1, 0, 0 };
int yyy[] = { -1, 0, 1, 1, 1, 0, -1, -1, 0 };

上下组合看,分别表示当前位置的相对位置,如 xxx[0] 的 -1 和 yyy[0] 的 -1,表示当前的横坐标 i-1 和纵坐标 j-1,刚好是当前位置的左上,其他同理
对于问题 2:
判断最终 i,j 的变化情况,设置范围即可

class Solution {
    public int[][] imageSmoother(int[][] M) {
        int xxx[] = { -1, -1, -1, 0, 1, 1, 1, 0, 0 };
        int yyy[] = { -1, 0, 1, 1, 1, 0, -1, -1, 0 };
        int m = M.length;
        int n = m == 0 ? 0 : M[0].length;
        if (m == 0 || n == 0)
            return null;
        int[][] N = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                int sum = 0;
                int num = 0;
                for (int k = 0; k < 9; k++) {
                    int x = i + xxx[k];
                    int y = j + yyy[k];
                    if (x >= 0 && x < m && y >= 0 && y < n) {
                        sum += M[x][y];
                        num++;
                    }
                }
                N[i][j] = sum / num;
            }
        }
        return N;
    }
}