# Very Clean Solution in Java

• Here we have a check function to check the boundary and a inner double loop to traverse the 9 potential candidates:

``````public class ImageSmoother {

public int[][] imageSmoother(int[][] M) {
if (M == null) return null;
int rows = M.length;
if (rows == 0) return new int[0][];
int cols = M[0].length;

int result[][] = new int[rows][cols];

for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
int count = 0;
int sum = 0;
for (int incR : new int[]{-1, 0, 1}) {
for (int incC : new int[]{-1, 0, 1}) {
if (isValid(row + incR, col + incC, rows, cols)) {
count++;
sum += M[row + incR][col + incC];
}
}
}
result[row][col] = sum / count;
}
}

return result;

}

private boolean isValid(int x, int y, int rows, int cols) {
return x >= 0 && x < rows && y >= 0 && y < cols;
}
}
``````

• The time consumption is 76ms in my case, longer than 98% of other submissions. Wonder what the cause is.

• Similar approach. All we have to do here is add all possible cells around a given point.Let's say the give is (x,y) then the possible cells around it will be the following:

``````  (x-1,y-1)| (x-1,y) |(x-1,y+1)
(x, y-1) |  {x,y}  |(x-1,y+1)
(x+1,y-1)| (x+1,y) |(x+1,y+1)
``````

Runtime ~40 ms

``````public int[][] imageSmoother(int[][] M) {
int row = M.length, col = M[0].length;
int[][] result = new int[row][col];
for(int i=0;i<row;++i){
for(int j=0;j<col;++j){
int total = 0, points = 0;
for(int k=i-1;k<i+2;++k){
if(k>-1 && k<row){
for(int l=j-1;l<j+2;++l){
if (l>-1 && l<col){
total+=M[k][l];
++points;
}
}
}
}
result[i][j] = (int) Math.floor(total/(double)points);
}
}

return result;
}``````

• Same idea with fewer loops and no helper method:

``````    public int[][] imageSmoother(int[][] matrix) {
if (matrix == null || matrix.length == 0) return new int[0][0];
int m = matrix.length, n = matrix[0].length;
int[][] res = new int[m][n];
int[][] moves = new int[][] {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {1, 1}, {1, -1}, {-1, 1}};
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int sum = matrix[i][j];
int count = 1;
for (int[] move : moves) {
int I = i + move[0];
int J = j + move[1];
if (I >= 0 && I < m && J >= 0 && J < n) {
count++;
sum += matrix[I][J];
}
}
res[i][j] = sum / count;
}
}
return res;
}
``````

• ``````    public int[][] imageSmoother(int[][] M) {
int m = M.length;
if(m == 0) return M;
int n = M[0].length;
int[][] res = new int[m][n];
int[][] dir = new int[][]{{0,1},{1,0},{1,1},{-1,0},{0,-1},{-1,-1},{-1,1},{1,-1}};
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
res[i][j] = check(M, dir, i, j);
}
}
return res;
}

int check(int[][] M, int[][] dir, int i, int j){
int m = M.length, n = M[0].length;
int count = 1;
int sum = M[i][j];
for(int[] row: dir){
int x = i + row[0];
int y = j + row[1];
if(x < 0 || y < 0 || x >= m  || y >= n){
continue;
}
sum += M[x][y];
count++;
}
return sum  /  count;
}``````

• ``````class Solution {
public int[][] imageSmoother(int[][] M) {
if (M == null || M.length == 0) {
return M;
}
int m = M.length, n = M[0].length;
int[][] res = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
helper(M, res, i, j);
}
}
return res;
}
public void helper(int[][] M, int[][] res, int i, int j) {
int sum = 0;
int count = 0;
int startRow = i - 1 >= 0? i - 1: 0;
int endRow = i + 1 <= M.length - 1? i + 1: M.length - 1;
int startCol = j - 1 >= 0? j - 1: 0;
int endCol = j + 1 <= M[0].length - 1? j + 1: M[0].length - 1;
for (int m = startRow; m <= endRow; m++) {
for (int n = startCol; n <= endCol; n++) {
sum += M[m][n];
count++;
}
}
res[i][j] = sum / count;
}
}
``````

• ``````            for (int incR : new int[]{-1, 0, 1}) {
for (int incC : new int[]{-1, 0, 1}) {
``````

Why not use two simple `for` loops, instead of initializing arrays? Initializing the arrays is a waste of space.

``````for (int incR = -1; i <= 1; i++) { ... }
``````

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.