알고리즘 문제를 풀다 보면 2차원 배열을 나선형(spiral) 형태로 채워야 하는 경우가 자주 등장합니다. 이번 글에서는 숫자 n을 입력받아 n×n 크기의 2차원 배열을 생성하고, 나선형 경로에 해당하는 위치에는 1을, 그 외의 위치에는 0을 채우는 JavaScript 함수를 구현해 보겠습니다.
문제 정의
하나의 숫자 n을 매개변수로 받는 JavaScript 함수를 작성해야 합니다. 이 함수는 n×n 크기의 2차원 배열을 만들어 반환하며, 시작점 [0, 0]에서 출발하는 나선형 경로의 모든 위치는 1로, 나머지 위치는 0으로 채워야 합니다.
예를 들어 n = 5일 때 기대되는 출력 결과는 다음과 같습니다.
[
[ 1, 1, 1, 1, 1 ],
[ 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 0, 1 ],
[ 1, 0, 0, 0, 1 ],
[ 1, 1, 1, 1, 1 ]
]바깥 테두리부터 안쪽으로 한 바퀴씩 감아 들어가며 1이 채워지는 것을 확인할 수 있습니다.
접근 방법: 경계 변수 활용하기
나선형 배열을 효율적으로 만드는 핵심은 네 개의 경계 변수를 사용하는 것입니다.
- left / right: 현재 채울 수 있는 열(column)의 범위
- top / bottom: 현재 채울 수 있는 행(row)의 범위
각 방향(오른쪽 → 아래 → 왼쪽 → 위)으로 이동하면서 값을 채운 뒤, 해당 방향의 경계를 2씩 줄여 나갑니다. 2씩 줄이는 이유는 나선이 한 바퀴 돌 때마다 안쪽에 두께 1짜리 빈 공간(0으로 남는 영역)이 생기기 때문입니다. 경계가 서로 교차하면 반복을 종료합니다.
구현 코드
전체 구현 코드는 다음과 같습니다.
const num = 5;
const spiralize = (num = 1) => {
const arr = [];
let x, y;
// num × num 크기의 배열을 0으로 초기화
for (x = 0; x < num; x++) {
arr[x] = Array.from({ length: num }).fill(0);
}
let left = 0;
let right = num;
let top = 0;
let bottom = num;
x = left;
y = top;
let h = Math.floor(num / 2);
while (left < right && top < bottom) {
// 1단계: 왼쪽 → 오른쪽
while (y < right) {
arr[x][y] = 1;
y++;
}
y--;
x++;
top += 2;
if (top >= bottom) break;
// 2단계: 위 → 아래
while (x < bottom) {
arr[x][y] = 1;
x++;
}
x--;
y--;
right -= 2;
if (left >= right) break;
// 3단계: 오른쪽 → 왼쪽
while (y >= left) {
arr[x][y] = 1;
y--;
}
y++;
x--;
bottom -= 2;
if (top >= bottom) break;
// 4단계: 아래 → 위
while (x >= top) {
arr[x][y] = 1;
x--;
}
x++;
y++;
left += 2;
}
// 짝수 크기일 때 중앙 처리
if (num % 2 == 0) arr[h][h] = 1;
return arr;
};
console.log(spiralize(num));실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
[
[ 1, 1, 1, 1, 1 ],
[ 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 0, 1 ],
[ 1, 0, 0, 0, 1 ],
[ 1, 1, 1, 1, 1 ]
]동작 원리 정리
- n×n 크기의 배열을 모두
0으로 초기화합니다. - 네 개의 경계(left, right, top, bottom)를 설정하고, 각 방향으로 이동하면서
1을 채웁니다. - 한 방향을 다 채울 때마다 해당 경계를 2씩 축소하여 다음 나선 라인으로 진입합니다.
- 경계끼리 교차하거나 역전되면 반복문을 종료합니다.
- n이 짝수인 경우, 마지막 중앙 지점
[h][h]를 별도로1로 마무리합니다.
이 알고리즘의 시간 복잡도는 O(n²)로, 배열의 모든 칸을 최대 한 번씩만 방문하므로 매우 효율적입니다. 나선형 매트릭스, 달팽이 배열 등 유사한 유형의 문제에도 동일한 경계 변수 기법을 그대로 응용할 수 있으니 꼭 기억해 두시길 바랍니다.