프로그래머스 코딩 문제 2021/08/02 - Lv.2 2개 이하로 다른 비트

이호현·2021년 8월 2일
0

Algorithm

목록 보기
130/138

[문제]

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

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

예를 들어,

  • f(2) = 3 입니다. 다음 표와 같이 2보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 3이기 때문입니다.
비트 다른 비트의 개수
2 000...0010
3 000...0011 1
  • f(7) = 11 입니다. 다음 표와 같이 7보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 11이기 때문입니다.
비트 다른 비트의 개수
7 000...0111
8 000...1000 4
9 000...1001 3
10 000...1010 3
11 000...1011 2

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

제한사항

  • 1 ≤ numbers의 길이 ≤ 100,000
  • 0 ≤ numbers의 모든 수 ≤ 1015

입출력 예

numbers result
[2,7] [3,11]

입출력 예 설명
입출력 예 #1

  • 문제 예시와 같습니다.

[풀이]

function solution(numbers) {
  return numbers.map(n => {
    if(!(n % 2)) {
      return n + 1;
    }
    else {
      const temp = '0' + n.toString(2);
      const idx = temp.lastIndexOf('0');
      const temp2 = temp.slice(0, idx) + '10' + temp.slice(idx + 2);
           
      return parseInt(temp2, 2);
    }
  });
}

numbers배열 안의 숫자들을 순회하면서 조건에 맞는 값으로 대체하기 위해 map을 사용하였다.

우선 이진수로 변환했을 때 짝수인 경우 끝자리가 무조건 0이므로 1이 증가한 값을 return해주면 된다.

홀수인 경우 끝에서 0의 위치를 찾고, 그 전까지는 1이므로 0110으로 바꾼 후 10진법으로 바꿔주면 된다.

예를 들어 이진법 변환 한 수가 1111일 경우 그 다음수는 10000이 된다.

2비트만 다른 가장 작은수는 10111인데 주어진 수인 1111의 앞에 0을 붙여 01111과 비교해보면 제일 왼쪽 두개만 바꿔주면 된다는걸 알수있다.

110011같은 경우도 1증가시키면 110100인데 2비트 다른 가장 작은수는 110101이다.

이것도 제일 처음 나오는 0과 그 오른쪽 1을 바꿔준 값이 답이 되는걸 알 수 있다.

처음에 생각했던 방식은 numbers의 요소를 1씩 증가시킨 후
원래 숫자와 ^로 비트 연산을 해서 1이 2개 이하가 되는 걸 찾으려고 했는데
비교하는 과정이 시간이 걸리기도하고, 1씩 증가시켜서 찾다보니 조건에 맞는 숫자를 찾는데
시간이 또 많이 걸릴수도 있어서 효율성에서 실패했다.
결국 힌트를 참고해서 풀었다.

profile
평생 개발자로 살고싶습니다

0개의 댓글