이번 글에서는 숫자 배열을 첫 번째 인수로, 그리고 하나의 숫자 n을 두 번째 인수로 받는 JavaScript 함수를 작성해 보겠습니다.
이 함수는 배열 안에 n개의 연속된 홀수가 존재하면 true를, 존재하지 않으면 false를 반환해야 합니다.
문제 이해하기
예를 들어, 입력 배열과 숫자가 다음과 같다고 가정해 봅시다.
const arr = [3, 5, 3, 5, 4, 3]; const n = 4;
이 경우 출력값은 true가 되어야 합니다. 왜냐하면 배열의 처음 네 개 숫자(3, 5, 3, 5)가 모두 홀수이기 때문입니다.
접근 방법
가장 효율적인 방법은 배열을 한 번만 순회하면서 연속된 홀수의 개수(스트릭)를 세는 것입니다.
- 현재 요소가 짝수라면 스트릭 카운터를 0으로 초기화합니다.
- 현재 요소가 홀수라면 스트릭 카운터를 1 증가시킵니다.
- 순회 도중 스트릭이 n에 도달하면 즉시
true를 반환합니다. - 배열 전체를 순회한 후에도 n에 도달하지 못했다면
false를 반환합니다.
이 방식은 시간 복잡도 O(n), 공간 복잡도 O(1)로 매우 효율적입니다.
예제 코드
const arr = [3, 5, 3, 5, 4, 3];
const n = 4;
const allOdd = (arr = [], n = 0) => {
if (!arr.length) {
return;
}
let streak = 0;
for (let i = 0; i < arr.length; i++) {
const el = arr[i];
if (el % 2 === 0) {
// 짝수를 만나면 연속 카운트 초기화
streak = 0;
} else {
// 홀수면 연속 카운트 증가
streak++;
}
if (streak === n) {
return true;
}
}
return false;
};
console.log(allOdd(arr, n));출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
true
코드 설명
함수 내부에서는 먼저 빈 배열인지 검사하여 빈 배열일 경우 아무것도 반환하지 않습니다. 이후 streak 변수를 사용해 현재까지 연속으로 등장한 홀수의 개수를 추적합니다.
요소를 순회하면서 나머지 연산자(%)를 활용해 짝수 여부를 판별하고, 짝수를 만나면 카운트를 초기화하며, 홀수를 만나면 카운트를 늘립니다. 카운트가 목표 값 n과 같아지는 순간 true를 반환하므로, 불필요한 추가 순회 없이 조기 종료할 수 있다는 점이 이 구현의 장점입니다.