문제 소개
0과 1로만 구성된 숫자 배열이 주어졌을 때, 이 배열을 받아 모든 1은 앞쪽으로, 모든 0은 뒤쪽으로 보내는 JavaScript 함수를 작성한다고 가정해 보겠습니다.
예를 들어 입력 배열이 다음과 같다면,
const arr = [1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1];
출력 결과는 다음과 같아야 합니다.
const output = [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
기본 풀이 코드
배열의 각 요소를 순회하면서, 값이 0이면 새 배열 끝에 추가(push)하고, 값이 1이면 앞쪽에 삽입(unshift)하는 방식으로 문제를 해결할 수 있습니다.
const arr = [1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1];
const sortBinary = arr => {
const copy = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] === 0) {
copy.push(0); // 0은 뒤로
} else {
copy.unshift(1); // 1은 앞으로
}
}
return copy;
};
console.log(sortBinary(arr));실행 결과
위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
[
1, 1, 1, 1, 1,
1, 0, 0, 0, 0,
0
]동작 원리
이 함수는 원본 배열을 변경하지 않고 새로운 배열(copy)을 생성합니다. 반복문 안에서 현재 요소가 0이면 결과 배열의 맨 뒤에 붙이고, 그렇지 않으면(즉 1이면) 맨 앞에 삽입합니다. 그 결과 1들이 자동으로 앞쪽에, 0들은 뒤쪽에 배치됩니다.
성능 개선 팁
unshift()는 배열의 모든 요소를 한 칸씩 뒤로 밀어내므로 시간 복잡도가 O(n)입니다. 따라서 위 방식은 전체적으로 O(n²)에 가까워질 수 있습니다. 배열의 크기가 클 경우에는 1의 개수를 먼저 세고 새 배열을 채우는 방식이 O(n)으로 훨씬 효율적입니다.
const sortBinaryFast = arr => {
const oneCount = arr.filter(v => v === 1).length;
return Array.from({ length: arr.length }, (_, i) =>
i < oneCount ? 1 : 0
);
};
console.log(sortBinaryFast(arr));
// [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]두 방법 모두 동일한 결과를 반환하지만, 데이터 크기가 커질수록 두 번째 방식이 성능 면에서 유리합니다.