Algorithm/프로그래머스

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

RIEN😚 2022. 5. 13. 16:47
728x90
반응형
 

코딩테스트 연습 - 2개 이하로 다른 비트

 

programmers.co.kr

 

문제

양의 정수 x에 대해 함수 f(x)는 다음과 같습니다.

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

정수들이 담긴 배열 numbers가 매개변수로 주어집니다.

numbers의 모든 수들에 대하여 각 수의 f 값을 배열에 차례대로 담아 return 하도록 solution 함수를 완성해주세요.

 

풀이

bit를 잘 생각해봅시다.🧐

 

짝수인 경우

마지막 bit(1)가 무조건 0입니다. 그럼 숫자보다 큰데 비트가 2개 이하로 다른 수는 무엇일까요?

넵, 마지막 bit에 1을 채워준 수, 즉 1 큰 수 입니다.😊

 

홀수인 경우

1xxxxx1로 이루어져 있습니다. 그럼 이 숫자보다 큰데 비트가 2개 이하로 다른 수는 무엇일까요?

먼저 큰 수를 만들기 위해서는 반드시 bit 1을 추가해 주어야 합니다.

 

1을 채우고 싶을 때 숫자는 가장 작게 만들고 싶을 때, 1의 최적의 위치는 마지막 bit에서부터 탐색할 때

가장 먼저 나오는 0bit를 1로 만들어주면 됩니다. 이 수를 A라고 하겠습니다.😀

예를 들어, 13이 입력으로 들어왔을 때 이 숫자를 bit로 바꾸면 1101입니다.

 

처음 나오는 bit를 1로 바꿔주면 1111이고 10진수로는 15입니다.

 

이제 저희는 bit 하나를 더 변경할 수 있습니다.

위에서 처럼 1로 변경하는 건 큰수를 만들 뿐입니다. 그러니 이번에는 1인 bit를 0으로 바꿔보겠습니다.

 

어느 위치의 bit를 0으로 바꿔야 할까요? 잘못 바꾸면 주어진 숫자보다 작아질 수 있습니다.

그러니 앞에 숫자 A를 만들 때 바꿨던 bit보다 뒤에 있는 bit를 0으로 바꿔주면 됩니다.

 

이전의 예제에서 바뀐 숫자는 15, 이진수로 1111입니다.

이 숫자를 만들 때는 뒤에서 두번째 bit를 1로 바꿔주었죠. 그럼 그 bit의 뒤에 있는 bit를 0으로 바꿔주겠습니다.

결과는 1110, 10진수로 14입니다.

 

이렇게 짝수인 경우 / 홀수인 경우로 나눠 쉽게 계산할 수 있습니다.😚

이번에는 코드로 구현해보겠습니다.

 

코드

import kotlin.math.*

class Solution {
    fun solution(numbers: LongArray): LongArray {
        return numbers.map{
            var num = it
            // 짝수인 경우
            if (num % 2 == 0L) {
                num + 1L
            } else { // 홀수인 경우
                // 첫 0 bit 찾아보기
                val i = getZeroIndex(it)
                (it + (2.0).pow(i) - (2.0).pow(i-1)).toLong()
            }
        }.toLongArray()
    }
    
    fun getZeroIndex(it: Long): Int {
        var num = it
        var i = 0
        while (true) {
            if (num % 2 == 0L) {
                break
            }
            num /= 2
            i++
        }
        return i
    }
}
반응형