숫자 배열을 입력받아, 배열의 요소들을 재배열했을 때 연속된 숫자 시퀀스를 만들 수 있는지 판별하는 JavaScript 함수를 작성해 보겠습니다.
예를 들어, 다음과 같은 배열이 있다고 가정해 봅시다.
const arr = [3, 1, 4, 2, 5];
이 배열의 요소들은 1부터 5까지 모든 숫자를 포함하고 있으므로, 재배열하면 [1, 2, 3, 4, 5]라는 연속된 시퀀스가 됩니다. 따라서 출력 결과는 true여야 합니다.
해결 접근 방식
이 문제는 다음과 같은 단계로 해결할 수 있습니다.
1. 빈 배열 처리
배열이 비어 있다면 연속된 시퀀스를 만들 수 없으므로 false를 반환합니다.
2. 배열 정렬
원본 배열은 그대로 유지하기 위해 복사본을 만든 후 오름차순으로 정렬합니다.
3. 연속성 검증
정렬된 배열의 첫 번째 값부터 시작하여, 각 요소가 이전 값보다 정확히 1씩 증가하는지 확인합니다. 하나라도 조건에 맞지 않으면 false를 반환합니다.
구현 코드
위 로직을 코드로 구현하면 다음과 같습니다.
const arr = [3, 1, 4, 2, 5];
const canBeConsecutive = (arr = []) => {
// 빈 배열인 경우 연속 시퀀스 불가
if (!arr.length) {
return false;
};
// 원본 배열 보호를 위해 복사 후 정렬
const copy = arr.slice();
copy.sort((a, b) => a - b);
// 첫 번째 값부터 시작해 1씩 증가하는지 확인
for (let i = copy[0], j = 0; j < copy.length; i++, j++) {
if (copy[j] === i) {
continue;
};
return false;
};
return true;
};
console.log(canBeConsecutive(arr));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
true
코드 설명
이 함수의 동작 원리를 자세히 살펴보면 다음과 같습니다.
- arr.slice(): 원본 배열의 변경을 방지하기 위해 복사본을 생성합니다.
- copy.sort((a, b) => a - b): 숫자 비교 함수를 전달하여 올바른 오름차순 정렬을 수행합니다. 기본 sort()는 문자열 기준으로 정렬하므로 반드시 비교 함수가 필요합니다.
- for 루프: 변수 i는 기대값(첫 요소부터 1씩 증가), 변수 j는 실제 인덱스 역할을 하며, 두 값이 일치하지 않으면 즉시 false를 반환해 불필요한 연산을 줄입니다.
추가 테스트 예시
다양한 입력에 대한 결과도 확인해 볼 수 있습니다.
console.log(canBeConsecutive([7, 8, 9, 10])); // true console.log(canBeConsecutive([1, 3, 5])); // false console.log(canBeConsecutive([5])); // true (단일 요소) console.log(canBeConsecutive([])); // false (빈 배열)
이처럼 정렬 기반의 간단한 검증 로직만으로도 배열이 연속된 숫자 시퀀스를 형성할 수 있는지 효율적으로 판별할 수 있습니다. 시간 복잡도는 정렬에 의해 O(n log n)입니다.