Algorithm/Programmers

[Java] 프로그래머스 (행렬 테두리 회전하기) Dev-Matching 2

팡우송 2021. 7. 31. 15:59

Problem : https://programmers.co.kr/learn/courses/30/lessons/77485

 

코딩테스트 연습 - 행렬 테두리 회전하기

6 6 [[2,2,5,4],[3,3,6,6],[5,1,6,3]] [8, 10, 25] 3 3 [[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]] [1, 1, 5, 3]

programmers.co.kr

 

Approach

행렬의 특정 부분을 회전시킴과 동시에, 그 영역에 있는 최솟값을 찾는 문제이다.

행렬 회전을 구현할 수 있어야 한다.

행렬 회전만 구현할 줄 안다면, 약간의 조건을 걸어 쉽게 풀이가 가능하다.

 

문제 풀이의 주요 로직은 아래와 같다.

  • 좌상단우하단의 위치를 찾고, 그 영역의 테두리 부분을 시계방향 90도 회전 시킨다.
  • 회전시킴과 동시에 그 테두리 영역에서의 최솟값을 찾는다.

위에서 찾은 최솟값 배열을 리턴해주기만 하면 된다.

 

Code

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;

public class MatrixEdgeRotate {
    static int[][] arr;
    public int[] solution(int rows, int columns, int[][] queries) {
        arr = new int[rows][columns];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                arr[i][j] = columns * i + j + 1;
            }
        }

        int[] ans = new int[queries.length];
        for (int i = 0; i < queries.length; i++) {
            ans[i] = rotate(queries[i][0], queries[i][1], queries[i][2], queries[i][3]);
        }

        return ans;
    }

    static int rotate(int r1, int c1, int r2, int c2) {
        r1--;
        c1--;
        r2--;
        c2--;

        int tmp = arr[r1][c1];
        int min = tmp;

        // 왼쪽 변 아래->위
        for (int i = r1; i < r2; i++) {
            arr[i][c1] = arr[i + 1][c1];
            min = Math.min(min, arr[i][c1]);
        }
        // 아랫변 오른->왼
        for (int i = c1; i < c2; i++) {
            arr[r2][i] = arr[r2][i + 1];
            min = Math.min(min, arr[r2][i]);

        }
        // 오른변 위->아래
        for (int i = r2; i > r1; i--) {
            arr[i][c2] = arr[i - 1][c2];
            min = Math.min(min, arr[i][c2]);

        }
        // 윗변 왼->오른
        for (int i = c2; i > c1; i--) {
            arr[r1][i] = arr[r1][i - 1];
            min = Math.min(min, arr[r1][i]);
        }
        arr[r1][c1 + 1] = tmp;

        return min;
    }

    @Test
    void test() {
        assertArrayEquals(new int[]{8, 10, 25}, solution(6, 6, new int[][]{{2, 2, 5, 4}, {3, 3, 6, 6}, {5, 1, 6, 3}}));
        assertArrayEquals(new int[]{1, 1, 5, 3}, solution(3, 3, new int[][]{{1, 1, 2, 2}, {1, 2, 2, 3}, {2, 1, 3, 2}, {2, 2, 3, 3}}));
        assertArrayEquals(new int[]{1}, solution(100, 97, new int[][]{{1, 1, 100, 97}}));
    }
}