이번 글에서는 숫자 배열을 첫 번째 인수로, 하나의 숫자를 두 번째 인수로 받는 JavaScript 함수를 작성해 보겠습니다.
이 함수는 배열 전체를 탐색하여 두 번째 인수로 전달된 숫자와 일치하는 모든 요소를 찾은 뒤, 해당 요소들을 배열의 맨 뒤로 이동시켜야 합니다. 일치하지 않는 나머지 요소들은 원래의 상대적인 순서를 그대로 유지합니다.
문제 예시
입력 배열이 다음과 같다고 가정해 보겠습니다.
const arr = [1, 5, 6, 6, 5, 3, 3];
두 번째 인수로 숫자 6을 전달하면, 값이 6인 모든 요소가 배열의 끝으로 밀려나 결과는 다음과 같아야 합니다.
const output = [1, 5, 5, 3, 3, 6, 6];
구현 코드
이 문제는 투 포인터(two-pointer) 기법을 활용하면 추가 배열 없이 제자리(in-place)에서 효율적으로 해결할 수 있습니다. 먼저 일치하지 않는 요소들을 앞쪽부터 차례대로 배치한 후, 남은 자리를 목표 숫자로 채우는 방식입니다.
const arr = [1, 5, 6, 6, 5, 3, 3];
const num = 6;
const shiftElement = (arr, num) => {
// 빈 배열인 경우 그대로 반환
if (arr.length === 0) {
return arr;
}
// num이 아닌 요소들을 앞쪽부터 배치
let index = 0;
for (let e of arr) {
if (e !== num) {
arr[index] = e;
index += 1;
}
}
// 나머지 자리를 num으로 채움
for (; index < arr.length; index++) {
arr[index] = num;
}
};
shiftElement(arr, num);
console.log(arr);실행 결과
위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
[ 1, 5, 5, 3, 3, 6, 6 ]
동작 원리 정리
이 알고리즘의 핵심은 다음과 같습니다.
1단계: 배열을 한 번 순회하면서 목표 숫자(num)가 아닌 요소들만 앞쪽 인덱스(index)에 덮어씁니다. 이 과정이 끝나면 index 변수는 num이 아닌 요소의 개수를 가리키게 됩니다.
2단계: index 위치부터 배열 끝까지 남은 모든 자리를 num으로 채워 넣습니다.
이 방식은 시간 복잡도 O(n), 공간 복잡도 O(1)로, 별도의 임시 배열을 만들지 않고도 문제를 해결할 수 있다는 장점이 있습니다.