알고리즘/LeetCode

[LeetCode] 661. Image Smoother - Java

반응형

https://leetcode.com/problems/image-smoother/description/

 

Image Smoother - LeetCode

Can you solve this real interview question? Image Smoother - An image smoother is a filter of the size 3 x 3 that can be applied to each cell of an image by rounding down the average of the cell and the eight surrounding cells (i.e., the average of the nin

leetcode.com


문제

An image smoother is a filter of the size 3 x 3 that can be applied to each cell of an image by rounding down the average of the cell and the eight surrounding cells (i.e., the average of the nine cells in the blue smoother). If one or more of the surrounding cells of a cell is not present, we do not consider it in the average (i.e., the average of the four cells in the red smoother).

Given an m x n integer matrix img representing the grayscale of an image, return the image after applying the smoother on each cell of it.

Example 1:

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

 

Example 2:

Input: img = [[100,200,100],[200,50,200],[100,200,100]]
Output: [[137,141,137],[141,138,141],[137,141,137]]
Explanation:
For the points (0,0), (0,2), (2,0), (2,2): floor((100+200+200+50)/4) = floor(137.5) = 137
For the points (0,1), (1,0), (1,2), (2,1): floor((200+200+50+200+100+100)/6) = floor(141.666667) = 141
For the point (1,1): floor((50+200+200+200+200+100+100+100+100)/9) = floor(138.888889) = 138

풀이

풀이 과정

image smoother는 이미지의 각 셀에 대해서 자신을 포함한 주변 3x3 크기의 정사각형 영역의 값의 평균을 구하여 현재 셀에 할당하도록 하는 필터이다. 이 때 3x3 크기의 정사각형안에 셀이 존재하지 않는 경우 해당 셀은 평균에 포함되지 않는 것으로 간주한다.

m x n 사이즈의 정수 배열 img가 주어졌을 때 image smoother 필터를 적용한 결과값을 return하는 문제이다.

 

먼저 결과값을 배열을 선언하고 img와 같은 크기로 초기화한다.

int[][] result = new int[img.length][img[0].length];

각 셀에 대해서 주변 셀을 탐색하기 위해 각 방향의 좌표 이동값을 정의한다.
(현재 좌표 기준 앞에서 부터 차례대로 왼쪽 위, 가운데 위, 오른쪽 위, 왼쪽, 오른쪽, 왼쪽 아래, 가운데 아래, 오른쪽 아래)

// 각 방향의 좌표 이동값 ( top left, top center, top right, left, right, bottom left, bottom center, bottom right )
int directions[][] = {{-1,-1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};

 

반복문을 통해 img 배열의 각 셀에 대해서 탐색한다.
주변 값의 평균을 구하기 위해 주변 셀 값의 합을 담을 sum과 주변 셀 개수의 합을 담을 cnt 변수를 선언한다.
초기값은 각각 현재 탐색 중인 셀 값과 그 개수인 1로 초기화한다.

// 각 셀에 대해서 탐색
for(int row = 0; row < img.length; row++) {
    for(int col = 0; col < img[0].length; col++) {
        // 주변 셀 값의 합 ( 초기값 = 현재 탐색 중인 셀 값 )
        int sum = img[row][col];
        // 주변 셀 개수 합 ( 초기값 = 현재 탐색 중인 셀 = 1 )
        int cnt = 1;
        
        ...
    }
}

 

이후 각 방향에 대해 탐색하는데 만약 이동한 좌표에 해당하는 셀이 배열을 벗어나는 경우는 탐색을 제외하고, 그렇지 않은 경우에는 그 값을 sum에 더하고 cnt를 증가 시킨다.
각 방향에 대한 탐색이 끝나면 sum을 cnt로 나누어 소수점을 버린 평균 값을 구하여 result 배열에 담는다.

// 각 방향에 대해 탐색
for(int[] dir : directions) {
    int curRow = row + dir[0];
    int curCol = col + dir[1];

    // 좌표가 배열을 벗어나는 경우 탐색 제외
    if(curRow < 0 || curCol < 0 || curRow >= img.length || curCol >= img[0].length) continue;

    sum += img[curRow][curCol];
    cnt++;
}

result[row][col] = sum / cnt;

 

모든 셀에 대한 탐색이 끝나면 완성된 result 배열을 return한다.

return result;

최종 코드

class Solution {
    public int[][] imageSmoother(int[][] img) {
        int[][] result = new int[img.length][img[0].length];
        // 각 방향의 좌표 이동값 ( top left, top center, top right, left, right, bottom left, bottom center, bottom right )
        int directions[][] = {{-1,-1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};

        // 각 셀에 대해서 탐색
        for(int row = 0; row < img.length; row++) {
            for(int col = 0; col < img[0].length; col++) {
                // 주변 셀 값의 합 ( 초기값 = 현재 탐색 중인 셀 값 )
                int sum = img[row][col];
                // 주변 셀 개수 합 ( 초기값 = 현재 탐색 중인 셀 = 1 )
                int cnt = 1;
                // 각 방향에 대해 탐색
                for(int[] dir : directions) {
                    int curRow = row + dir[0];
                    int curCol = col + dir[1];

                    // 좌표가 배열을 벗어나는 경우 탐색 제외
                    if(curRow < 0 || curCol < 0 || curRow >= img.length || curCol >= img[0].length) continue;

                    sum += img[curRow][curCol];
                    cnt++;
                }

                result[row][col] = sum / cnt;
            }
        }

        return result;
    }
}