읽기 전
- 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다.
- 개인적으로 배운 점을 정리한 글입니다.
문제 링크
문제 풀이 - 탐색
탐색으로 해결하는 방법과 비트마스킹 2가지의 풀이가 있다. 필자는 탐색으로 풀었으나 이 문제에 효율성 체크 항목이 었었다면 통과하지 못했을 것이다.
n보다 크고 1-2개의 비트가 다른 수이면서 그 중 가장 작은 수이므로 끝에서부터 탐색하다가 처음으로 0을 만나는 지점에서 1로 바꾸고 그 직전의 값을 0으로 바꾸면 되겠다. 만약 뒷자리가 없으면 그대로 리턴한다.
- 주어진 수를 2진수로 변한한뒤 스트링으로 바꾸고 배열에 넣는다. 혹시 1로만 이루어진 수일 수도 있으므로 앞에 "0"을 추가해둔다.
- 뒤에서부터 탐색하여 처음으로 만나는 0을 1로 바꾸고 그 직전 값을 0으로 바꾼다. 직전 좌표가 없다면 그대로 리턴
python 코드
def solution(numbers):
def convert(n):
s = bin(n)[2:]
buf = ["0"]
for c in s:
buf.append(c)
for i in range(len(buf) - 1, -1, -1):
if buf[i] == "1":
continue
elif buf[i] == "0":
buf[i] = "1"
if i < len(buf) - 1:
buf[i + 1] = "0"
break
s = "".join(buf)
res = 0
for i, c in enumerate(s[::-1]):
res += int(c) * (2 ** i)
return res
answer = []
for n in numbers:
answer.append(convert(n))
return answer
문제 풀이 - 비트마스킹
값 n에 대해 n + 1 & ~n은 n의 이진수의 0자리가 1로 변한 값이다. 이 값을 P라 하고 이 값을 n과 or 연산하면 가질 수 있는 최댓값이 된다. 1로만 구성된 값이면 n + 1로 자리수가 늘어난 길이가 갖는 최댓값으로 바뀐다.
비트 반전된 P에 대해 오른쪽으로 1비트 움직인 뒤 비트를 반전시키면 기존값과 비교해 0이 있던 자리는 1이 되고 그 다음 자리는 0이 될 상태일 것이다. 이 반전된 값을 방금 구했던 최댓값과 and 연산하면 된다.
python 코드
def solution(numbers):
answer = []
for n in numbers:
p = n + 1 & ~n
M = p | n
p >>= 1
p = ~p
answer.append(p & M)
return answer
'Algorithms > Programmers' 카테고리의 다른 글
Programmers. 징검다리 건너기 (0) | 2021.09.09 |
---|---|
Programmers. 호텔 방 배정 (0) | 2021.09.09 |
Programmers. 짝수 행 세기 (0) | 2021.09.09 |
Programmers. 트리 트리오 중간값 (0) | 2021.09.09 |
Programmers. 약수의 개수와 덧셈 (0) | 2021.09.09 |