[프로그래머스] 2개 이하로 다른 비트 JavaScript

·2024년 7월 19일

문제

양의 정수 x에 대한 함수 f(x)를 다음과 같이 정의합니다.

x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수
예를 들어,

f(2) = 3 입니다. 다음 표와 같이 2보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 3이기 때문입니다.

f(7) = 11 입니다. 다음 표와 같이 7보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 11이기 때문입니다.

정수들이 담긴 배열 numbers가 매개변수로 주어집니다. numbers의 모든 수들에 대하여 각 수의 f 값을 배열에 차례대로 담아 return 하도록 solution 함수를 완성해주세요.

제한 사항

1 ≤ numbers의 길이 ≤ 100,000
0 ≤ numbers의 모든 수 ≤ 10^15

입력

numbers : [2,7]

출력

[3,11]

내가 했던 풀이 방법

  1. getNumber 함수의 인자로 현재 수를 넣어준다.
  2. 해당 수가 짝수일 경우 number의 1을 더한 값을 return 한다. (짝수일 경우, 마지막 비트가 항상 0이기 때문에 마지막 비트를 1로 바꿔주면 된다.)
  3. 홀수인 경우, number를 2진수로 변환해준다. 2진수에 0이 포함되어 있지 않을 경우에는 number를 2진수로 변환한 값에 맨 앞을 "10"을 추가해준다. (맨 앞에 10을 추가해주지 않으면 비트 차이가 2개 이상인 조건을 지킬 수가 없다.)
  4. 3번의 경우가 아닐 때는 가장 오른쪽에 있는 0의 위치를 알아낸다. 그 다음 0을 1로 바꾸고 바로 오른쪽에 위치한 1을 0으로 바꿔준다.

코드

function solution(numbers) {
    var answer = [];
    
    for(let i=0; i<numbers.length; i++) {
        answer.push(getNumber(numbers[i]));
    }
    
    return answer;
}

function getNumber(number) {
    if (number % 2 === 0) {
        return number + 1;
    }
    
    let checkBit = number.toString(2);
    if (!checkBit.includes('0')) {
        return parseInt('10' + checkBit.slice(1), 2);
    }
    
    let lastZeroIndex = checkBit.lastIndexOf('0');
    let nextBit = checkBit.slice(0, lastZeroIndex) + '10' + checkBit.slice(lastZeroIndex + 2);
    return parseInt(nextBit, 2);
}

회고

비트 문제는 진짜 바로 풀이한 적이 없는 것 같다. 2진수로 변환하고 해당 수보다 큰 값들 중에 비트 차이가 2개 이하로 나는 수를 찾도록 풀이했는데 10번 11번 케이스에서 시간초과가 발생했다. 그래도 새로운 메소드도 공부하기도 했고... 의미있는 풀이였다.

profile
Frontend🍓

0개의 댓글