자주 나오는 회전/중력 하강 코드에 대해 정리해보겠습니다.
2차원 배열 회전
원본 배열은 아래로 정의하겠습니다.
| 1 | 2 | 3 | |
|---|---|---|---|
| 1 | 1 | 2 | 3 |
| 2 | 4 | 5 | 6 |
| 3 | 7 | 8 | 9 |
시계방향(오른쪽) 90도 회전
| 1 | 2 | 3 | |
|---|---|---|---|
| 1 | 7 | 4 | 1 |
| 2 | 8 | 5 | 2 |
| 3 | 9 | 6 | 3 |
public static int[][] rotateClockwise(int[][] matrix) {
int n = matrix.length;
int[][] result = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
result[j][n - 1 - i] = matrix[i][j];
}
}
return result;
}
반시계방향(왼쪽) 90도 회전
| 1 | 2 | 3 | |
|---|---|---|---|
| 1 | 3 | 6 | 9 |
| 2 | 2 | 5 | 8 |
| 3 | 1 | 4 | 7 |
public static int[][] rotateCounterClockwise(int[][] matrix) {
int n = matrix.length;
int[][] result = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
result[n - 1 - j][i] = matrix[i][j];
}
}
return result;
}
180도 회전
public static int[][] rotate180(int[][] matrix) {
int n = matrix.length;
int[][] result = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
result[n - 1 - i][n - 1 - j] = matrix[i][j];
}
}
return result;
}
벽이 없고 그냥 중력 하강
public static void gravityFallNoObstacle(int[][] board) {
int rows = board.length;
int cols = board[0].length;
for (int col = 0; col < cols; col++) {
int emptyRow = rows - 1;
for (int row = rows - 1; row >= 0; row--) {
if (board[row][col] != 0) { //물체가 있을때
board[emptyRow][col] = board[row][col];
if (emptyRow != row) {
board[row][col] = 0;
}
emptyRow--;
}
}
}
}
벽이 있고 중력 하강
public static void gravityFallWithObstacle(int[][] board) {
int rows = board.length;
int cols = board[0].length;
// 각 열=col에 대해 반복하여 중력 하강을 적용합니다. 열 단위로 하는 이유는 중력 하강이 각 열을 독립적으로 아래로 떨어뜨리는 방식이기 때문
for (int col = 0; col < cols; col++) {
//emptyRow는 물체가 떨어질 가장 낮은 빈 공간을 나타내는 변수로, 처음에는 배열의 가장 아래 위치(rows - 1)에서 시작합니다.
int emptyRow = rows - 1;
//배열의 아래에서 위로 (rows - 1부터 0까지) 각 행을 순회
//아래에서부터 확인하는 이유는, 물체가 아래로 떨어질 때 빈 공간을 채우기 위한 위치를 효율적으로 찾기 위해서
for (int row = rows - 1; row >= 0; row--) {
if (board[row][col] == -1) { //벽일때
//현재 위치에 벽(-1)이 있는 경우, emptyRow를 벽 바로 위(row - 1)로 설정
emptyRow = row - 1;
} else if (board[row][col] != 0) { //물체가 있는 경우
//현재 위치가 0(빈 공간)이 아닌, 즉 물체가 있는 경우 해당 물체를 emptyRow 위치로 이동
board[emptyRow][col] = board[row][col];
//만약 emptyRow와 row가 다르면(즉, 물체가 아래로 이동했다면), 물체가 원래 위치했던 board[row][col]을 0으로 만들어 기존 위치를 빈 공간으로 변경
if (emptyRow != row) {
board[row][col] = 0;
}
//다음 물체가 쌓일 위치를 한 칸 위로 이동시킴
//이를 통해 현재 물체가 변경되면, 그 바로 위로 다음 물체가 쌓이도록 함
emptyRow--;
}
}
}
}