https://school.programmers.co.kr/learn/courses/30/lessons/77485
이러한 행렬이 있다고 가정하자.
여기서 특정 부분을 회전해야 하는데, 그 영역은 다음과 같이 주어진다.
``(x1, y1, x2, y2)``
만약 ``(2, 2, 5, 4)``라고 했을 때, 회전은 다음과 같이 이루어져야 한다.
좌표는 배열의 실제 인덱스에 1이 더해진 형태로 주어짐을 알 수 있다.
사실 이런 문제만 나오면 쫄기만 했다.
다차원 배열의 원소의 위치를 바꾼다는 게 머릿속에 잘 그려지지 않았기 때문이다.
그리고 "회전"이라는 키워드가 괜히 문제의 난도를 높이는 느낌이기도 했다.
그렇지만 이번 문제는 그리 나쁘지 않았다.
먼저 배열 초기화부터.
친절하게도 순서대로 쫙 밀기만 하면 된다.
let matrix = Array.from({ length: rows }, (_, i) =>
Array.from({ length: columns }, (_, j) => i * columns + j + 1)
);
let result = [];
바로 밀어주고 결과를 담을 배열 ``result``도 선언해 준다.
``queries``도 2차원 배열의 형태로 온다.
배열의 원소로 배열을 가진다는 뜻.
그럼 각 배열마다의 회전을 반복문 안에서 돌리면 될 것이다.
queries.forEach(query => {
// 좌표값에서 1을 빼 0으로 시작하게 함
let [x1, y1, x2, y2] = query.map(i => i - 1);
// 회전하기
}
이런 흐름이 될 것이라고 생각할 수 있다.
그리고 이 문제는 단순히 자리를 바꾸는 게 아니라 한 칸씩 미는 것이다.
사각틀 안에 나무 블럭이 꽉 차있는 상태에서 회전시킬 여유가 있을까?
당연히 불가능할 것이다.
여기서 회전 영역의 시작 좌표 즉, ``(x1, y1)``을 잠시 빼둔다.
// 회전 전 빈칸 만들기 [x1][y1]
let temp = matrix[x1][y1];
let minValue = temp;
그리고 해당 사이클의 최저값으로 미리 빼둔 값을 넣어두고 비교를 시작하게 된다.
이제 반시계로 돌면서 각 원소들을 하나씩 당긴다.
빈칸을 만들면서 하나씩 당겨주는 게 편하기 때문이다.
다 당기고 나면 빈칸은 자연스럽게 ``(x1, y1 + 1)``이 된다.
그럼 거기에 킵해둔 값을 넣어주면 회전 처리가 끝난다.
// 왼쪽 (상 > 하)
for (let i = x1; i < x2; i++) {
matrix[i][y1] = matrix[i + 1][y1];
minValue = Math.min(minValue, matrix[i][y1]);
}
// 아래쪽 (좌 > 우)
for (let i = y1; i < y2; i++) {
matrix[x2][i] = matrix[x2][i + 1];
minValue = Math.min(minValue, matrix[x2][i]);
}
// 오른쪽 (하 > 상)
for (let i = x2; i > x1; i--) {
matrix[i][y2] = matrix[i - 1][y2];
minValue = Math.min(minValue, matrix[i][y2]);
}
// 위쪽 (우 > 좌)
for (let i = y2; i > y1; i--) {
matrix[x1][i] = matrix[x1][i - 1];
minValue = Math.min(minValue, matrix[x1][i]);
}
// 킵 해둔 temp를 빈칸에 넣음
matrix[x1][y1 + 1] = temp;
// 회전 사이클마다 최소값 추가
result.push(minValue);
빈칸을 계속 만들어주면서 진행하게 된다.
매 사이클마다 ``Math.min()``을 통해 최저값을 구하는 것도 잊지 않는다.
모든 사이클이 완료되면 최저값을 ``result``에 넣어주고 다음 쿼리를 수행한다.
결과는 다음과 같이 나왔다.
다 하고 나니 떠오른 건데,
첫 배열 초기화를 단순 반복문으로 바꾸고 최저값 계산도 ``Math.min``을 굳이 쓸 필요가 없다는 생각이 들었다.
편리함 함수들로 인해 코드가 간결해졌지만 콜백 오버헤드를 마냥 무시할 순 없을 것이다.
'Camp > T.I.L.' 카테고리의 다른 글
[TIL #26] 함수 오버로딩의 함정 (0) | 2024.10.18 |
---|---|
[TIL #25] 전력망을 둘로 나누기 (0) | 2024.10.16 |
[TIL #23] Product Price at a Given Date (0) | 2024.10.10 |
[TIL #22] 실시간으로 달리는 공룡 (0) | 2024.10.07 |
[TIL #21] 큰 수 만들기 (0) | 2024.10.04 |