Algorithm/Programmers
[Java] 프로그래머스 (행렬 테두리 회전하기) Dev-Matching 2
팡우송
2021. 7. 31. 15:59
Problem : https://programmers.co.kr/learn/courses/30/lessons/77485
Approach
행렬의 특정 부분을 회전시킴과 동시에, 그 영역에 있는 최솟값을 찾는 문제이다.
행렬 회전
을 구현할 수 있어야 한다.
행렬 회전
만 구현할 줄 안다면, 약간의 조건을 걸어 쉽게 풀이가 가능하다.
문제 풀이의 주요 로직은 아래와 같다.
좌상단
과우하단
의 위치를 찾고, 그 영역의테두리
부분을시계방향 90도
회전 시킨다.- 회전시킴과 동시에 그 테두리 영역에서의 최솟값을 찾는다.
위에서 찾은 최솟값 배열을 리턴해주기만 하면 된다.
Code
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
public class MatrixEdgeRotate {
static int[][] arr;
public int[] solution(int rows, int columns, int[][] queries) {
arr = new int[rows][columns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
arr[i][j] = columns * i + j + 1;
}
}
int[] ans = new int[queries.length];
for (int i = 0; i < queries.length; i++) {
ans[i] = rotate(queries[i][0], queries[i][1], queries[i][2], queries[i][3]);
}
return ans;
}
static int rotate(int r1, int c1, int r2, int c2) {
r1--;
c1--;
r2--;
c2--;
int tmp = arr[r1][c1];
int min = tmp;
// 왼쪽 변 아래->위
for (int i = r1; i < r2; i++) {
arr[i][c1] = arr[i + 1][c1];
min = Math.min(min, arr[i][c1]);
}
// 아랫변 오른->왼
for (int i = c1; i < c2; i++) {
arr[r2][i] = arr[r2][i + 1];
min = Math.min(min, arr[r2][i]);
}
// 오른변 위->아래
for (int i = r2; i > r1; i--) {
arr[i][c2] = arr[i - 1][c2];
min = Math.min(min, arr[i][c2]);
}
// 윗변 왼->오른
for (int i = c2; i > c1; i--) {
arr[r1][i] = arr[r1][i - 1];
min = Math.min(min, arr[r1][i]);
}
arr[r1][c1 + 1] = tmp;
return min;
}
@Test
void test() {
assertArrayEquals(new int[]{8, 10, 25}, solution(6, 6, new int[][]{{2, 2, 5, 4}, {3, 3, 6, 6}, {5, 1, 6, 3}}));
assertArrayEquals(new int[]{1, 1, 5, 3}, solution(3, 3, new int[][]{{1, 1, 2, 2}, {1, 2, 2, 3}, {2, 1, 3, 2}, {2, 2, 3, 3}}));
assertArrayEquals(new int[]{1}, solution(100, 97, new int[][]{{1, 1, 100, 97}}));
}
}