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

JavaScript에서 두 번·한 번만 나타나는 숫자 두 개 찾는 방법

문제 정의

어떤 배열에는 모든 숫자가 세 번씩 나타나지만, 딱 하나의 숫자만 두 번 나타나고 또 다른 하나의 숫자는 한 번만 나타난다고 가정해 봅시다. 우리가 작성해야 할 JavaScript 함수는 이 배열을 입력받아 두 번 나타나는 숫자와 한 번 나타나는 숫자를 찾아 반환하는 것입니다.

예를 들어 [1, 1, 1, 2, 2, 3]이라는 배열이 주어지면, 숫자 1은 세 번, 숫자 2는 두 번, 숫자 3은 한 번 나타나므로 함수는 [3, 2]를 반환해야 합니다.

예제 코드

다음은 위 문제를 해결하는 코드입니다 −

const arr = [1, 1, 1, 2, 2, 3];
const findMissing = (arr = []) => {
    let x = 0;
    let y = 0;
    for(let i = 0; i < arr.length; i++){
       if(arr.filter(a => a === arr[i]).length === 2){
          y = arr[i];
       };
       if(arr.filter(b => b === arr[i]).length === 1){
          x = arr[i];
       };
    };
    return [x, y];
};
console.log(findMissing(arr));

코드 동작 원리

이 함수는 배열의 각 요소를 순회하면서 filter 메서드를 사용해 자신과 같은 값의 개수를 셉니다. 개수가 정확히 2개인 요소는 변수 y에, 개수가 1개인 요소는 변수 x에 차례대로 저장하고, 최종적으로 [x, y] 형태의 배열을 반환합니다.

출력 결과

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

[3, 2]

성능 개선 팁

위 방식은 매 요소마다 filter를 호출하기 때문에 시간 복잡도가 O(n²)입니다. 배열이 길어질수록 비효율적이므로, Map 객체로 각 숫자의 등장 횟수를 한 번에 집계하면 O(n)으로 최적화할 수 있습니다.

const findMissingOptimized = (arr = []) => {
    const count = new Map();
    arr.forEach(num => count.set(num, (count.get(num) || 0) + 1));
    let once = 0, twice = 0;
    for(const [num, c] of count){
       if(c === 1) once = num;
       if(c === 2) twice = num;
    };
    return [once, twice];
};
console.log(findMissingOptimized([1, 1, 1, 2, 2, 3])); // [3, 2]

두 코드 모두 동일한 결과를 반환하지만, 데이터 크기가 클수록 Map 기반 접근 방식이 훨씬 빠른 성능을 보여줍니다.