본문 바로가기

Programming/코딩테스트 준비

[프로그래머스] 행렬 테두리 회전하기

728x90

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

 

풀이

이차원 배열을 다루는 구현 문제였다.

자바 언어로 이차원 배열을 동적 할당하고 다루는 것이 처음엔 낯설었지만 몇번 하다 보니 적응되었다.

이차원 배열 내에서 직사각형 테두리를 시계방향으로 한칸씩 이동하는 것을 구현하는 데에 시간이 좀 걸렸다.

기본 컨셉은 (x1,y1)을 시작점으로 꼬리물기처럼 반시계방향으로 인덱스를 가져가서 ↑←↓→ 순으로 한칸씩 이동해서 값을 덮어썼다.

처음 (x1,y1) 지점의 값을 임시로 저장해뒀다가 꼬리물기의 마지막으로 (x1,y1+1) 지점에 값을 넣어서 이동을 마무리했다.

한칸씩 이동할 때마다 이동한 값이 해당 쿼리에서의 최소값인지를 체크해서 한번의 쿼리가 끝나면 최소값을 answer에 추가했다.

코드

import java.util.*;
class Solution {
    public int[] solution(int rows, int columns, int[][] queries) {
        int[] answer = new int[queries.length];
        // 행렬 m 선언 및 초기화
        int[][] m = new int[rows][columns];
        for(int i = 1; i <= rows; i++)
            for(int j = 1; j <= columns; j++)
                m[i - 1][j - 1] = (i - 1) * columns + j;
        
        // 회전 목록 수행
        int x1, y1, x2, y2;
        for(int k = 0; k < queries.length; k++){
            x1 = queries[k][0] - 1;
            y1 = queries[k][1] - 1;
            x2 = queries[k][2] - 1;
            y2 = queries[k][3] - 1;
            
            int x1y1_val = m[x1][y1];   // (x1,y1) 임시저장
            int min_val = x1y1_val;     // 최솟값
            
            // ↑ 방향
            for(int i = x1; i < x2; i++){
                m[i][y1] = m[i + 1][y1];
                min_val = Math.min(min_val, m[i][y1]);
            }
            // ← 방향
            for(int j = y1; j < y2; j++){
                m[x2][j] = m[x2][j + 1];
                min_val = Math.min(min_val, m[x2][j]);
            }
            // ↓ 방향
            for(int i = x2; i > x1; i--){
                m[i][y2] = m[i - 1][y2];
                min_val = Math.min(min_val, m[i][y2]);
            }
            // → 방향 ((x1,y1+1)은 따로)
            for(int j = y2; j > y1 + 1; j--){
                m[x1][j] = m[x1][j - 1];
                min_val = Math.min(min_val, m[x1][j]);
            }
            m[x1][y1 + 1] = x1y1_val;
            
            // 가장 작은 숫자 배열에 담기
            answer[k] = min_val;
        }
        
        return answer;
    }
}