프로그래머스-2021 Dev-Matching: 웹 백엔드 ( 행렬 테두리 회전 by Java )

Flash·2022년 2월 13일
0

Programmers-Algorithm

목록 보기
32/52
post-thumbnail

구현 ( 배열 )

프로그래머스 2021 Dev-Matching: 웹 백엔드 개발자 (상반기) Level 2 문제 행렬 테두리 회전하기Java를 이용해 풀어보았다.
이차원 배열 가지고 푸는 구현 문제였다.

문제 링크 첨부한다.
https://programmers.co.kr/learn/courses/30/lessons/77485


배열 값 변경하기

화려한 기술이 필요하진 않은 문제같다. 그냥 주어진 조건대로 배열을 잘 다룰 수 있는지만 확인하는 문제같다. 그냥... 힘으로 푸는 문제 같았다.
위 그림과 같이 시계 방향으로 배열 값들을 회전시켜주면 된다. 주의할 것은 안쪽에 있는 원소들은 그냥 놔둬야한다는 점.

나는 r1, r2, c1, c2에 대해서 4 파트로 나누어 작업을 했다. 위 그림에서 초록색 원으로 둘려싸여 있는 부분들을 미리 저장해놨다가, 4 파트에 대해 다 저장을 마쳤으면 각 파트들을 한 칸씩 밀어서 배열 값을 갱신해주는 형태로 진행했다.
즉 아래 그림과 같이 값들을 이동시켜준 것이다.
코드를 어떻게 하면 짧게 직관적으로 짤 수 있을까 고민하다가, 짧게는 굳이 필요한가 싶어서 어차피 연산도 그리 많지 않은 작업.. 그냥 길게 늘여썼다.
rotate 메소드 코드만 살펴보면 다음과 같다. param으로 전달되는 int[][] next는 현재 배열 상태를 넘겨주는 거고, 결국 이 배열이 다음 배열로 갱신되어 return 되는 것이다.

static int[][] rotate(int[] query, int[][] next){
        int r1 = query[0]-1;    int c1 = query[1]-1;
        int r2 = query[2]-1;    int c2 = query[3]-1;

        int[] part1 = new int[c2-c1];   int[] part2 = new int[r2-r1];
        int[] part3 = new int[c2-c1];   int[] part4 = new int[r2-r1];

        /** 네 파트 값 저장해두기 */
        int i=0;
        for(int c=c1; c<=c2-1; c++) // part1 저장
            part1[i++] = next[r1][c];

        i=0;
        for(int r=r1; r<=r2-1; r++) // part2 저장
            part2[i++] = next[r][c2];

        i=0;
        for(int c=c2; c>=c1+1; c--) // part3 저장
            part3[i++] = next[r2][c];

        i=0;
        for(int r=r2; r>=r1+1; r--) // part4 저장
            part4[i++] = next[r][c1];

        /** 여기부터 새로운 값 채워 넣기 */
        i=0;
        for(int c=c1+1; c<=c2; c++){ // part1 한 칸 밀어주기
            result = Math.min(result, part1[i]);
            next[r1][c] = part1[i++];
        }

        i=0;
        for(int r=r1+1; r<=r2; r++){ // part2 한 칸 밀어주기
            result = Math.min(result, part2[i]);
            next[r][c2] = part2[i++];
        }

        i=0;
        for(int c=c2-1; c>=c1; c--){ // part3 한 칸 밀어주기
            result = Math.min(result, part3[i]);
            next[r2][c] = part3[i++];
        }

        i=0;
        for(int r=r2-1; r>=r1; r--){ // part4 한 칸 밀어주기
            result = Math.min(result, part4[i]);
            next[r][c1] = part4[i++];
        }

        return next;
    }

한 칸씩 밀어서 채워넣을 때에 문제에서 요구하는 값인 가장 작은 녀석을 찾아주는 작업을 해준다. Math.min() 메소드를 이용해서 최솟값을 갱신해나갔다.

solution 코드를 보면 다음과 같다.

int[] solution(int rows, int columns, int[][] queries) {
        int[] answer = new int[queries.length];
        int[][] next = new int[rows][columns];
        int value = 1;
        for(int r=0; r<rows; r++) // 기본 형태 배열 만들어주기
            for(int c=0; c<columns; c++)
                next[r][c] = value++;

        for(int i=0; i<queries.length; i++) {
            next = rotate(queries[i], next);
            answer[i] = result;
            result = Integer.MAX_VALUE;
        }
        return answer;
    }

그냥... 열심히 푸면 되는 문제였다. 이런 형태 문제가 시험에 나온다면 어렵지 않게 풀긴 하겠지만 이런 수준의 문제를 풀 줄 안다고 잘 하는 건 아니기 때문에 풀고 나도 뭔가 성취감이 없다...ㅠ 어려운 문제 가서는 어차피 막힐텐데.. 가슴이 아프다..!!


아래는 내가 제출한 전체 코드다.

public class MatrixRotation {
    static int result = Integer.MAX_VALUE;

    static int[] solution(int rows, int columns, int[][] queries) {
        int[] answer = new int[queries.length];
        int[][] next = new int[rows][columns];
        int value = 1;
        for(int r=0; r<rows; r++)
            for(int c=0; c<columns; c++)
                next[r][c] = value++;

        for(int i=0; i<queries.length; i++) {
            next = rotate(queries[i], next);
            answer[i] = result;
            result = Integer.MAX_VALUE;
        }
        return answer;
    }

    static int[][] rotate(int[] query, int[][] next){
        int r1 = query[0]-1;    int c1 = query[1]-1;
        int r2 = query[2]-1;    int c2 = query[3]-1;

        int[] part1 = new int[c2-c1];   int[] part2 = new int[r2-r1];
        int[] part3 = new int[c2-c1];   int[] part4 = new int[r2-r1];

        /** 네 파트 값 저장해두기 */
        int i=0;
        for(int c=c1; c<=c2-1; c++) // part1 저장
            part1[i++] = next[r1][c];

        i=0;
        for(int r=r1; r<=r2-1; r++) // part2 저장
            part2[i++] = next[r][c2];

        i=0;
        for(int c=c2; c>=c1+1; c--) // part3 저장
            part3[i++] = next[r2][c];

        i=0;
        for(int r=r2; r>=r1+1; r--) // part4 저장
            part4[i++] = next[r][c1];

        /** 여기부터 새로운 값 채워 넣기 */
        i=0;
        for(int c=c1+1; c<=c2; c++){ // part1 한 칸 밀어주기
            result = Math.min(result, part1[i]);
            next[r1][c] = part1[i++];
        }

        i=0;
        for(int r=r1+1; r<=r2; r++){ // part2 한 칸 밀어주기
            result = Math.min(result, part2[i]);
            next[r][c2] = part2[i++];
        }

        i=0;
        for(int c=c2-1; c>=c1; c--){ // part3 한 칸 밀어주기
            result = Math.min(result, part3[i]);
            next[r2][c] = part3[i++];
        }

        i=0;
        for(int r=r2-1; r>=r1; r--){ // part4 한 칸 밀어주기
            result = Math.min(result, part4[i]);
            next[r][c1] = part4[i++];
        }

        return next;
    }

    public static void main(String[] args) {
        int rows = 6;
        int columns = 6;
        int[][] queries = {{2,2,5,4},{3,3,6,6},{5,1,6,3}};
        int[] answer = solution(rows,columns,queries);
        for(int a: answer) System.out.println(a);
    }
}
profile
개발 빼고 다 하는 개발자

0개의 댓글