[JAVA] 프로그래머스 - 행렬 테두리 회전하기 LV2
문제는 아래 링크를 통해 확인해주세요.
조건
- rows, columns가 주어지면 규칙에 맞게 matrix를 초기화한다. (+1씩 증가하는 규칙! i행 j열의 수는 ((i-1) x columns + j) 이라는 규칙이 있다고 지문에 나와있기도 한다.)
- rows와 columns는 2 이상 100 이하
- queries의 각 행은 [x1, y1, x2, y2]로 이루어지고, 행(회전)의 개수는 1 이상 10,000 이하
- x1과 x2는 1 이상 rows 이하, y1과 y2는 1 이상 columns 이하
- 회전을 한 값들 중 최솟값을 구하여 배열에 담아야 한다.
- 시계방향으로 회전한다.
- 회전 시 테두리의 값들만 변화가 있다. 시작위치(왼쪽 위)는 x1, y1이고 끝(오른쪽 아래) 위치는 x2, y2이다.
설계
1. 좌측부터 (한칸씩 위로) 회전을 해준다. 그리고 좌측을 회전시키면서 덮이는 (x1,y1) 인덱스는 따로 임시 저장해두고,
이미 좌측은 회전시켰으니 좌측과 겹치는 부분을 덮어도 상관없기 때문에
2. 아래를 (왼쪽으로) 회전시킨다.
이미 아래쪽은 회전시켰으니 아래쪽과 겹치는 부분을 덮어도 상관없기 때문에
3. 우측을 (아래로) 회전시킨다.
이미 우측은 회전시켰으니 우측과 겹치는 부분을 덮어도 상관없기 때문에
4. 그다음은 top을 (오른쪽으로) 회전시킨다.
5. 마지막으로 행렬의 (x1,y1+1) 위치는 임시 저장해둔 변수로 덮었다.
(5번을 해주지 않으면, x1, y1+1은 회전되지 않은 값으로 존재한다.)
내 생각
처음에는 각 행마다 처리를 해주려 했다.
x가 x1일 때 오른쪽으로 이동
x2가 x2일 때 왼쪽으로 이동
그 외일 때 좌측은 위로 이동, 우측은 아래로 이동
그리고 오른쪽과 왼쪽으로 이동할 때는 -1과 +1의 규칙을, 아래와 위로 이동할 때는 +rows와 -rows의 규칙을 갖는다고 생각했다.
통과되지 않아서 다시 그림을 보니.. 무조건 rows만큼 증가하는게 아니었다. 첫 회전은 그렇지만 계속 회전을 반복할 수록 규칙이 있지 않구나를 느꼈다.. 처음부터 봤어야 했는데
그래서 '그냥 순차적으로 값을 덮어줘야겠구나' 생각을 하고 방향을 틀었다. 이때 중요한 것은
어디를 시작 지점으로 정하고 어떤 순서로 회전을 시켜야 temp 변수를 최대한 적게 생성하면서 어떠한 값에도 회손되지않고 회전을 시킬 수 있을지 고민했다.
시간을 너무 쓰기도 했고.. 중간 중간 코드를 참고했지만 다시 잡힌 방향대로 코드를 작성해보았다.
코드
쿼리 개수만큼 회전 로직을 거치는데, 이를 메서드로 추출할 수도 있겠다.
import java.util.Arrays;
public class 행렬테두리회전하기 {
public int[] solution(int rows, int columns, int[][] queries) {
int[] answer = new int[queries.length];
int[][] matrix = new int[rows][columns];
int n = 0;
// 1. 초기화
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++)
matrix[i][j] = ++n;
}
//2.회전
for (int i = 0; i < queries.length; i++) {
int x1 = queries[i][0] - 1;
int y1 = queries[i][1] - 1;
int x2 = queries[i][2] - 1;
int y2 = queries[i][3] - 1;
// 좌측 회전
int temp = matrix[x1][y1]; // 시작 위치값 임시 저장
int min = temp;
for (int j = x1; j < x2; j++) {
matrix[j][y1] = matrix[j + 1][y1];
if (min > matrix[j][y1]) min = matrix[j][y1];
}
// bottom 회전
for (int j = y1; j < y2; j++) {
matrix[x2][j] = matrix[x2][j + 1];
if (min > matrix[x2][j]) min = matrix[x2][j];
}
// 우측 회전
for (int j = x2; j > x1; j--) {
matrix[j][y2] = matrix[j - 1][y2];
if (min > matrix[j][y2]) min = matrix[j - 1][y2];
}
// top 회전
for (int j = y2; j > y1; j--) {
matrix[x1][j] = matrix[x1][j - 1];
if (min > matrix[x1][j]) min = matrix[x1][j];
}
matrix[x1][y1+1] = temp; // 덮인 값을 임시저장해논 값으로 지정
// 3. 한 queries마다 min값을 answer에 저장
answer[i] = min;
}
return answer;
}
public static void main(String[] args) {
행렬테두리회전하기 t = new 행렬테두리회전하기();
int[][] queries = {{2,2,5,4}, {3,3,6,6}, {5,1,6,3}};
System.out.println(Arrays.toString(t.solution(6, 6, queries)));
}
}
추가로, 위 문제는 구현 문제인데 시뮬레이션 및 구현 문제를 잘 다룰 수 있도록 알려주는 글이 있다.
보고 나니 필자가 작성한 코드는 수정이 필요한 코드라 생각이 들었다.
이 글을 참고해보면 좋을 것 같다.
피드백과 댓글은 환영입니다.