th42500의 TIL

[Java] 2021 Dev-Matching: 웹 백엔드 개발(상반기) - 행렬 테두리 회전하기 (Lv2) 본문

Algorithm/Programmers

[Java] 2021 Dev-Matching: 웹 백엔드 개발(상반기) - 행렬 테두리 회전하기 (Lv2)

th42500 2022. 8. 3. 01:28

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

✔ 입출력 예시

행렬 테두리 회전하기 입출력 예시

 

 

💡 풀이방법 및 포인트

1️⃣ 행렬 회전은 회전하고자 하는 방향의 반대의 방향의 인덱스의 숫자를 끌어와야 함

     

      위의 예시를 이용하여 설명하자면...

      1️⃣ 먼저 가장 첫번째 수를 다른 변수에 보관

            (예시는 왼쪽 테두리부터 행렬을 회전하기 위해 8을 보관)

     2️⃣ 그림과 같이 반시계방향(빨간색 번호 순서)으로 인덱스의 수 옮겨주기

     3️⃣ 행렬을 회전하기 전에 넣어뒀던 첫번째 값을 행렬 회전의 마지막 인덱스에 삽입

처음에 보관했던 수를 행렬 회전의 마지막 인덱스에 삽입한 결과

2️⃣ 위의 1️⃣번 행렬 회전을 queries배열의 길이만큼 반복하면서 각 과정에서 최솟값 찾아서 정답배열에 담기

 

 

✔ 소스코드

import java.util.Arrays;

public class Solution { // 행렬 테두리 회전하기

	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 rows = 3;
//		int columns = 3;
//		int[][] queries = {{1, 1, 2, 2},{1, 2, 2, 3},{2, 1, 3, 2}, {2, 2, 3, 3}};
//		int rows = 100;
//		int columns = 97;
//		int[][] queries = {{1, 1, 100, 97}};

// 테스트 케이스 예시
//		int rows = 3;
//		int columns = 4;
//		int[][] queries = {{1, 1, 2, 2}, {1, 2, 2, 3}, {1, 3, 2, 4}, {2, 3, 3, 4}};
		int rows = 3;
		int columns = 5;
		int[][] queries = {{1, 1, 2, 2}, {2, 3, 3, 4}, {1, 2, 3, 4}, {1, 1, 3, 4}, {2, 2, 3, 5}};

		System.out.println(solution(rows, columns, queries));
	}

	private static int[] solution(int rows, int columns, int[][] queries) {
		int[] answer = new int[queries.length];
		
		int[][] matrix = new int[rows+1][columns+1];  // 행렬의 인덱스를 조금 더 편하게 이용하기 위해 행, 열에 +1
		
		// 배열 입력
		int idx = 1;
		for (int i = 1; i <= rows; i++) { 
			for (int j = 1; j <= columns; j++) {
				matrix[i][j] = idx;
				idx++;
			}
		}
		
		// 행렬 회전 (어디에 있는 인덱스의 값을 가져오는지)
		int[] dr = {1, 0, -1, 0};  // 하 우 상 좌
		int[] dc = {0, 1, 0, -1};  // 하 우 상 좌
		
		for(int i=0; i<queries.length; i++) {  // queries의 배열길이만큼 행렬 회전
			int d = 0;  // 방향 인덱스
			int sr = queries[i][0];  // 시작행 인덱스
			int sc = queries[i][1];  // 시작열 인덱스
			int first = matrix[sr][sc];  // 처음 수 보관
			int min = matrix[sr][sc];  // 가장 작은 수 초기화

			while(d < 4) {  // 방향 배열이 끝날때까지 반복 (회전)
				int nr = sr + dr[d];  // 값을 가져올 행 인덱스
				int nc = sc + dc[d];  // 값을 가져올 열 인덱스
				
				if(0 < nr && nr <= rows && 0 < nc && nc <= columns) {
					matrix[sr][sc] = matrix[nr][nc];  // 값 이동
					min = Math.min(min, matrix[nr][nc]);  // 가장 작은 값 찾기
				}
				
                // 기존 인덱스 변경
				sr = nr;  
				sc = nc;
				
				// 각 모서리까지 인덱스 값 옮겼다면 방향전환
				if((d==0 && nr == queries[i][2]) || (d==1 && nc == queries[i][3]) || (d == 2 && nr == queries[i][0]) || (d == 3 && nc == queries[i][1])) {
					d++;
				}
			}
			matrix[queries[i][0]][queries[i][1]+1] = first;  // 첫번째 값 이동
			answer[i] = min;  // 해당 회전에서 가장 작은 수 정답 배열에 담기
		}
		
		return answer;
	}
}

 

 

❗ 결과

👉 테스트 통과

 

행렬 회전은 신중하게 생각하지 않으면 많이 헷갈릴 수 있는 문제..💦

이번 문제를 통해 행렬 회전 알고리즘을 복습할 수 있는 기회였다 🔥

Comments