평범한 필기장

[Programmers_Python] 2개 이하로 다른 비트 본문

코딩 테스트 준비/Programmers

[Programmers_Python] 2개 이하로 다른 비트

junseok-rh 2023. 4. 4. 12:17

https://school.programmers.co.kr/learn/courses/30/lessons/77885

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

내가 생각한 풀이 방식

  • 이진수에 0이 있는 경우와 없는 경우 2가지 경우로 나누어서 생각했다.
  • 이진수에 0이 없을 경우, 맨앞 1을 0으로 바꾸고 앞자리에 1을 추가한다. (예 111 -> 1011)
  • 이진수에 0이 있을 경우, 0들 중에서 맨뒤에 있는 0을 1로 바꾼다.

이렇게 풀 경우 5의 경우 101인데 111로 바뀌게 된다. 하지만 101의 경우 110이 되어야 2비트 이하로 바꾸면서 최소가 된다.

def solution(numbers):
    answer = []
    for num in numbers:
        k = str(bin(num)[:2])
        a = list(str(bin(num))[2:])
        n = len(a)
        if '0' in a:
            for i in range(len(a)):
                if a[n-1-i] == '0':
                    a[n-1-i] = '1'
                    break
        else:
            new_lst = ['1']
            for i in range(len(a)):
                if a[i] == '1':
                    a[i] = '0'
                    break
            new_lst.extend(a)
            a = new_lst
        answer.append(int(k + (''.join(a)),2))
    return answer

정답 코드

 다른 분들의 정답코드를 보니, 0이 있는 경우와 없는 경우로 나눠야 하는 것이 아니라 홀수일 경우와 짝수일 경우로 나눠야한다.

  • 짝수의 경우는 항상 마지막 자리수가 0이기 때문에 1로 바꾸면 2비트 이하로 바꾸는 최소의 수가 된다.
  • 홀수의 경우는 이진수에 0이 있을수도 있고 없을수도 있다. 그래서 이진수 맨 앞자리에 0을 추가해주고 이진수의 맨 오른쪽 0 위치를 찾고 그 위치의 값을 1로 바꾸고 그 다음 위치의 값을 0으로 하면 2비트만 바꾸고 최소의 수를 구할 수 있다.
def solution(numbers):
    answer = []
    for num in numbers:
        k = str(bin(num)[:2])
        a = list('0' + str(bin(num))[2:])
        ind = ''.join(a).rfind('0')
        a[ind] = '1'
        if num%2 == 1:
            a[ind + 1] = '0'
        answer.append(int((k + ''.join(a)),2))
    return answer