包含整数的二维矩阵 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
注意:
- 给定矩阵中的整数范围为 [0, 255]。
- 矩阵的长和宽的范围均为 [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;
}
}