JavaScript에서 숫자 배열이 주어졌을 때, 연속된 음수들이 하나의 그룹(클러스터)을 이루는 횟수를 세야 하는 경우가 있습니다. 예를 들어 다음과 같은 배열이 있다고 가정해 보겠습니다.
const arr = [-1,-2,-1,0,-1,-2,-1,-2,-1,0,1,0];
위 배열에서 음수 덩어리는 두 군데 존재합니다. 첫 번째는 -1,-2,-1로 이루어진 그룹, 두 번째는 -1,-2,-1,-2,-1로 이루어진 그룹입니다. 즉, 우리가 작성해야 할 함수는 이처럼 음수끼리 연속된 그룹의 개수를 반환해야 합니다.
해결 접근 방식
가장 깔끔한 방법은 배열의 reduce() 메서드를 활용하는 것입니다. 각 요소를 순회하면서 다음 조건을 확인합니다.
- 현재 값이 음수(
val < 0)인지 확인합니다. - 동시에 바로 다음 값이 0 이상(
arr[ind+1] >= 0)인지 확인합니다. - 두 조건이 모두 참이라면, 현재 위치가 하나의 음수 클러스터의 마지막 지점이라는 의미이므로 카운트를 1 증가시킵니다.
이 방식은 각 클러스터의 끝에서만 카운트하기 때문에, 같은 클러스터 내부의 여러 음수가 중복으로 계산되지 않습니다.
구현 코드
const arr = [-1,-2,-1,0,-1,-2,-1,-2,-1,0,1,0];
const countClusters = arr => {
return arr.reduce((acc, val, ind) => {
if(val < 0 && arr[ind+1] >= 0){
acc++;
};
return acc;
}, 0);
};
console.log(countClusters(arr));코드 설명
reduce()의 초기값은 0으로 설정되어 있으며, 배열을 순회하면서 조건에 맞을 때마다 누적값 acc가 증가합니다. 마지막 인덱스에서 arr[ind+1]은 undefined가 되는데, undefined >= 0은 false로 평가되므로 안전하게 동작합니다. 만약 배열이 음수로 끝나는 경우까지 처리하고 싶다면, 마지막 요소가 음수일 때도 카운트하도록 조건을 보완할 수 있습니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
2
배열에는 두 개의 서로 다른 음수 클러스터가 존재하므로 결과값은 2가 됩니다. 이 패턴은 시간 복잡도 O(n)으로 한 번의 순회만으로 해결되므로, 긴 배열에서도 효율적으로 동작합니다.