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;
}
}
❗ 결과
👉 테스트 통과
행렬 회전은 신중하게 생각하지 않으면 많이 헷갈릴 수 있는 문제..💦
이번 문제를 통해 행렬 회전 알고리즘을 복습할 수 있는 기회였다 🔥