반응형
1. 문제
- m x n 크기의 2차원 배열이 주어질 때, 그림과 같이 탐색하여 요소를 순서대로 담은 배열을 반환하라.
2. 풀이
function spiralOrder(matrix: number[][]): number[] {
let i = 0, j = 0; // i, j 인덱스
let m = matrix.length, n = matrix[i].length; // 배열 크기.
const result = []; // 결과를 담을 배열.
let dir: 'right' | 'down' | 'left' | 'up' = 'right'; // matrix 방향 정보.
while(result.length < m * n) { // 배열이 가득찰 때 까지 반복.
result.push(matrix[i][j]);
matrix[i][j] = -101; // 문제에서 제공되는 정수 범위를 벗어나서 아무거나 지정.
if(dir === 'right') { // 오른쪽인 경우,
if(j !== n-1 && matrix[i][j+1] !== -101) { // j가 마지막 인덱스가 아니고, 방문한 적 없다면
j++; // j 증가.
} else { // j가 마지막 요소 또는 방문한 적 있는 요소라면
dir = 'down'; // down 방향 전환
i++; // i증가.
}
} else if(dir === 'down') {
if(i !== m-1 && matrix[i+1][j] !== -101) {
i++;
} else {
dir = 'left';
j--;
}
} else if(dir === 'left') {
if(j !== 0 && matrix[i][j-1] !== -101) {
j--;
} else {
dir = 'up';
i--;
}
} else if(dir === 'up') {
if(i !== 0 && matrix[i-1][j] !== -101) {
i--;
} else {
dir = 'right';
j++;
}
}
}
return result;
};
- 메인 컨셉은 요소의 방문 여부를 알고, 방향을 전환하는 것이라고 생각했다. 겉이야 끝에 도달했는지로 판단하면 되지만, 안에 있는 애들은 언제 방향을 전환해야 하는 지 모른다.
- 이걸 위해서 방문했던 요소를 다른 값으로 변경시키는 방식을 사용했다.
- 처음에는 두 번째 예제를 고려하지 않아서 애가 겉은 잘 도는데 안을 안돌아서 방법을 바꿨다.
- 위치와 상관없이 방향 정보와 범위를 고려해서 인덱스를 이동시킨다.
- right 설명만 적긴 했는데, 나머진 똑같다.
- -101은 큰 의미가 없고 그냥 배열에 담길 수 있는 요소의 범위가 -100 <= x <= 100 이기 때문에 이 범위만 벗어나면 상관없다.
- 처음에는 0으로 체크했다가 테스트 케이스 실패..