본문으로 바로가기

programmers. 행렬 테두리 회전하기

category Algorithm/문제 2021. 6. 16. 17:15

문제

링크

 

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

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

풀이

딱히 필요한 자료구조나 스킬이 필요한 문제는 아니고 구현 문제이다

시계 방향으로 테두리만 회전시키면 되는 문제이고 4개의 테두리중 한 개씩 이동하면된다

제일 윗 줄부터 원소를 하나씩 오른쪽으로 밀어서 회전시킨다고 가정하면

1 2 3
4 5 6
7 8 9
1 1 3
4 5 6
7 8 9

2가 1로 덮어씌워졌기 때문에 3에 2를 넣을 수 없는 문제가 생겼다

이 처럼 다음 인덱스에 원소를 옮기기 전에 그 인덱스에 해당하는 원소를 미리 저장해놓아야하는 번거러움이 생긴다

반대로 왼쪽 테두리부터 당겨서 회전시킨다고 생각해보면

1 2 3
4 5 6
7 8 9
4 2 3
7 5 6
7 8 9

왼쪽 테두리 당기기

4 2 3
7 5 6
8 8 9

아래 테두리 당기기

4 4 2
7 5 3
8 9 6

오른쪽 테두리 당기기

남은 건 윗 줄인데 역시나 덮어 씌워야할 1이 사라져있다

하지만 밀어서 회전시키는 것과 다르게 우리가 신경써야 주어야할 원소는 시작 원소 1 하나 뿐

1을 임시로 저장해 두었다가 회전이 끝난 후 시작 원소의 오른쪽 인덱스에 덮어 씌우면 회전이 끝난다

4 1 2
7 5 3
8 9 6

코드

function solution(rows, columns, queries) {
        var answer = [];
        const board = Array(rows).fill(0).map((_,r)=>Array(columns).fill().map((_,c)=>(c+1)+(r*columns)));
        queries.forEach(v=> {
            answer.push(rotate(v.map(v => v - 1)));
        });

        function rotate(arr){
            // console.group();
            const [startY, startX] = [arr[0],arr[1]];
            const [endY, endX] = [arr[2],arr[3]];

            const temp = board[startY][startX];

            let min = Infinity;

            // 왼쪽 세로 줄
            for(let i=startY; i<endY;i++){
                    board[i][startX] = board[i+1][startX];
                    min = Math.min(min,(board[i][startX]));
                }


            // 밑 줄
            for(let i=startX; i<endX;i++){
               board[endY][i] = board[endY][i+1];
                min = Math.min(min,board[endY][i]);
            }
            // 오른쪽 세로 줄
            for(let i=endY; i>startY;i--){
                board[i][endX] = board[i-1][endX];
                min = Math.min(min,board[i][endX]);
            }

            // 윗 줄
            for(let i=endX; i>startX;i--){
                board[startY][i] = board[startY][i-1];
                min = Math.min(min,board[startY][i]);
            }

            board[startY][startX+1] = temp;
            min = Math.min(min,board[startY][startX+1]);
            // console.log(JSON.parse(JSON.stringify(board)));
            // console.groupEnd();


            return min;
        }

        function rangeCheck(number,range){
            return number <= range && number >= 0;
        }

        return answer;
    }