문제 후기
문제를 보고 가장 먼저 고민한 것은 15(1111)과 30(11110)과 같이 다음 오는 숫자가 자릿수가 증가하는 경우였습니다.
다른 것은 어떻게 하면 쉽게 숫자를 넘겨줄 수 있을까라는 생각을 했고 Queue와 배열을 고민하다 문제를 풀면서 queue의 의미가 없다고 생각하여 배열을 사용했습니다.
해결 방식은 위에서부터 1인경우 pass하고 0이 나왔다면 0과 1의 자리를 바꾸고 뒤는 가장 작은 수를 배치하는 것입니다.
1001110 에서 1001110 -> 1010110로 바꾸고 뒤의 110은 가장 작은 수로 변경해야하므로 0의 갯수만큼 먼저 합치고, 그 이후 1을 합쳐서 1010011이 되는 방식입니다.
문제 설명
자연수 n이 주어졌을 때, n의 다음 큰 숫자는 다음과 같이 정의 합니다.
- 조건 1. n의 다음 큰 숫자는 n보다 큰 자연수 입니다.
- 조건 2. n의 다음 큰 숫자와 n은 2진수로 변환했을 때 1의 갯수가 같습니다.
- 조건 3. n의 다음 큰 숫자는 조건 1, 2를 만족하는 수 중 가장 작은 수 입니다.
예를 들어서 78(1001110)의 다음 큰 숫자는 83(1010011)입니다.
자연수 n이 매개변수로 주어질 때, n의 다음 큰 숫자를 return 하는 solution 함수를 완성해주세요.
Python 코드
def solution(n):
arr = [] # n을 2진수로 변환
res = [] # n 다음 숫자의 2진수
# n 숫자를 2진수로 변환
while n >= 2:
if n % 2 == 0:
arr.append(0)
else:
arr.append(1)
n = n // 2
arr.append(1)
tmp = [] # 임의의 배열
zero, one = 0,0 #
val = 1 #
result = 0 # 결과값.
# n의 2진수로부터 시작
for idx in range(len(arr)-1):
k = arr[idx]
# 만약 해당 값이 1이고 그 다음 값이 0인 경우 서로 변경.
if k == 1 and arr[idx+1] == 0:
# zero와 one을 이용하여 바꾼 부분 뒤를 가장 작은 수로 만듬.
for i in range(one):
res.append(1)
for j in range(zero):
res.append(0)
res.append(arr[idx+1]) # 1과 0을 서로 변경.
res.append(1)
# 나머지 부분을 합침.
res.extend(arr[idx+2:])
# 2진수 -> 10진수
for x in res:
result += val * x
val *= 2
return result
# 바꾸기 전의 1의 갯수
elif k == 1:
one += 1
# 바꾸기 전의 0의 갯수
elif k == 0:
zero += 1
# 만약 위에서 return이 안된 경우, 더이상 바꾸는 것으로 증가 안되는 경우
for j in range(one):
tmp.append(1)
for i in range(zero):
tmp.append(0)
# 2번째에 0을 추가하여 1의 갯수도 같으면서 다음 큰 수
tmp.append(0)
tmp.append(1)
for x in tmp:
result += val * x
val *= 2
return result
'프로그래머스' 카테고리의 다른 글
[프로그래머스] 땅따먹기 -Python (0) | 2020.11.26 |
---|---|
[프로그래머스] 이진 변환 반복하기 -Python (0) | 2020.11.24 |
[프로그래머스] 튜플 -Python (0) | 2020.11.20 |
[프로그래머스] 올바른 괄호 -Python (0) | 2020.11.20 |
[프로그래머스] 가장 큰 정사각형 찾기 - Python (0) | 2020.11.17 |