Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

두 개의 배열을 합쳐 연속된 수열을 만들 수 있는지 확인하는 방법 - JavaScript

이번 글에서는 숫자로 이루어진 두 개의 배열을 인수로 받는 JavaScript 함수를 작성해 보겠습니다.

이 함수는 두 배열을 하나로 합친 뒤 임의의 순서로 재배열했을 때, 연속된 수열(연속적인 시퀀스)을 만들 수 있으면 true를, 만들 수 없으면 false를 반환해야 합니다.

예를 들어, 입력 배열이 다음과 같다고 가정해 보겠습니다.

const arr1 = [4, 6, 2, 9, 3];
const arr2 = [1, 5, 8, 7];

두 배열을 합치면 [4, 6, 2, 9, 3, 1, 5, 8, 7]이 되고, 이를 정렬하면 [1, 2, 3, 4, 5, 6, 7, 8, 9]로 1부터 9까지 빠짐없이 이어지는 연속된 수열입니다. 따라서 출력 결과는 true여야 합니다.

문제 해결 접근 방식

이 문제는 다음 세 단계로 해결할 수 있습니다.

1. 두 배열을 하나로 합치기

전개 연산자(spread operator)를 사용해 두 배열의 모든 요소를 새로운 배열에 담습니다.

2. 배열을 오름차순으로 정렬하기

sort() 메서드에 비교 함수 (a, b) => a - b를 전달하여 숫자 크기순으로 정렬합니다. 비교 함수를 생략하면 문자열 기준으로 정렬되므로 반드시 명시해야 합니다.

3. 인접 요소 간의 차이가 일정한지 검사하기

정렬된 배열에서 첫 번째 요소와 두 번째 요소의 차이를 공차(common difference)로 저장한 뒤, 나머지 인접 요소들의 차이가 이 공차와 같은지 순회하며 확인합니다. 중간에 하나라도 다르면 즉시 false를 반환합니다.

예제 코드

위 접근 방식을 구현한 전체 코드는 다음과 같습니다.

const arr1 = [4, 6, 2, 9, 3];
const arr2 = [1, 5, 8, 7];

const canFormSequence = (arr1, arr2) => {
    // 두 배열을 하나로 합침
    const combined = [...arr1, ...arr2];

    // 요소가 2개 미만이면 항상 수열로 볼 수 있음
    if (combined.length < 2) {
        return true;
    }

    // 오름차순 정렬
    combined.sort((a, b) => a - b);

    // 첫 두 요소의 차이를 공차로 설정
    const commonDifference = combined[0] - combined[1];

    // 인접 요소 간 차이가 공차와 일치하는지 검사
    for (let i = 1; i < combined.length - 1; i++) {
        if (combined[i] - combined[i + 1] === commonDifference) {
            continue;
        }
        return false;
    }
    return true;
};

console.log(canFormSequence(arr1, arr2));

출력 결과

콘솔에 출력되는 결과는 다음과 같습니다.

true

동작 원리 정리

배열 [4, 6, 2, 9, 3]과 [1, 5, 8, 7]을 합쳐 정렬하면 [1, 2, 3, 4, 5, 6, 7, 8, 9]가 되고, 인접한 모든 요소의 차이가 일정하게 유지됩니다. 따라서 최종적으로 true가 반환됩니다.

반대로 예를 들어 arr1 = [4, 6, 2, 9], arr2 = [1, 5, 8]처럼 수열 중간에 빠진 숫자가 있다면 정렬 후 차이가 일정하지 않아 false가 반환됩니다.

이 알고리즘은 정렬에 O(n log n)의 시간 복잡도를 가지며, 이후 순회 과정은 O(n)이므로 전체적으로 효율적인 편입니다. 참고로 위 코드는 인접 요소 간 차이가 일정한 등차수열인지를 검사하는 방식이므로, 반드시 1씩 증가하는 연속 정수만 허용하고 싶다면 공차가 -1(오름차순 기준)인지 추가로 확인하면 됩니다.