문제 정의
여러 개의 값을 담고 있는 배열 X(예: [-3, 5, 1, 3, 2, 10])가 주어졌을 때, 배열에 포함된 모든 음수 값을 제거하는 함수를 작성하는 것이 목표입니다. 함수의 실행이 끝나면 배열에는 양수만 남아 있어야 합니다.
단, 이 문제에는 두 가지 중요한 제약 조건이 있습니다.
- 임시 배열을 생성하면 안 됩니다. 원본 배열을 그대로 수정하는 in-place 방식으로 처리해야 합니다.
- 요소를 제거할 때는 pop() 메서드만 사용해야 합니다.
해결 아이디어
핵심은 배열의 뒤에서부터 처리하는 것입니다. 먼저 배열 맨 끝에 연속해서 있는 음수들을 pop()으로 잘라내면, 배열의 마지막 요소는 항상 양수(또는 0)가 됩니다. 이후 뒤에서 앞으로 순회하면서 음수를 발견하면, 그 자리를 배열의 마지막 요소(양수가 보장된 값)로 덮어쓴 뒤 pop()으로 마지막 요소를 제거합니다.
뒤에서부터 순회하기 때문에 교체 대상이 되는 마지막 요소는 이미 검사가 끝난 값이므로 안전하며, 이 방식은 추가 배열 없이 원본 배열 안에서 문제를 해결하고 시간 복잡도는 O(n)입니다.
예제 코드
function removeNegatives(x) {
// 1) 배열 끝에 연속된 음수는 바로 제거
while (x.length && x[x.length - 1] < 0) {
x.pop();
}
// 2) 뒤에서 앞으로 순회하며 남은 음수 처리
for (var i = x.length - 1; i >= 0; i--) {
if (x[i] < 0) {
// 현재 요소를 마지막 요소(양수 보장)로 교체한 뒤 제거
x[i] = x[x.length - 1];
x.pop();
}
}
return x;
}
console.log(removeNegatives([-3, 5, 1, 3, 2, 10]));
실행 결과
콘솔에는 다음과 같이 음수가 모두 제거된 배열이 출력됩니다.
[ 5, 1, 3, 2, 10 ]
정리
이 알고리즘은 임시 배열 없이 pop() 단 하나의 메서드만으로 음수를 제거합니다. 배열을 역방향으로 순회하면서 음수를 발견하면 마지막 양수와 자리를 바꾼 뒤 잘라내는 방식이기 때문에, 공간 복잡도 O(1)로 매우 효율적으로 동작합니다. 배열을 직접 수정해야 하는 제약 조건이 있는 코딩 테스트나 실무 로직에서 유용하게 활용할 수 있는 패턴입니다.