본문 바로가기

Algorithm/[이코테] 알고리즘 유형별 기출문제

[이코테] 다이나믹 프로그래밍 문제 - 못생긴 수 python

난이도 : ●◐○ | 풀이 시간 : 30분 | 시간 제한 : 1초 | 메모리 제한 : 128MB | 기출 : Google 인터뷰

문제

  • 2, 3, 5만을 소인수로 가지는 수를 못생긴 수라고 한다.
  • n번째 못생긴 수를 찾는 프로그램을 작성하라.

입력조건

  • 첫째 줄에 n이 입력된다.(1<=n<=2,000)

출력조건

  • n번째 못생긴 수를 출력한다.

 

입력예시

10

출력예시

4

 

아이디어

  • 못생긴 수를 저장할 집합 s를 생성한다.
  • 집합 s에 첫 번째 못생긴 수인 1을 추가한다.
  • x를 첫 번째 못생긴 수인 1로 초기화한다.
  • while문을 돌면서 x*2, x*3, x*5한 것이 s에 없다면 추가한다.
  • 집합 s의 원소 개수가 n이 되면 반복을 종료한다.
  • s에 마지막으로 추가된 수를 출력한다.

오답코드

n = int(input())
s = set()
s.add(1)
x = 1
flag = False
while True:
for i in (x*2,x*3,x*5):
if i not in s:
s.add(i)
if len(s)==n:
flag = True
break
if flag:
break
x += 1
print(list(s)[-1])
  • 집합의 길이가 n이 되었을 때 집합에 n번째로 추가된 수가 항상 n번째 못생긴 수라는 보장이 없기 때문에 틀렸다.
  • x*2, x*3, x*5 중에 가장 작은 값으로 다시 *2, *3, *5를 해야 바르게 n번째 못생긴 수를 구할 수 있다는 것을 깨달았다.

 

정답코드

n = int(input())
# n개의 못생긴 수를 저장할 리스트
ugly = [0]*n
# 첫 번째 못생긴 수는 1
ugly[0] = 1
# 2배, 3배, 5배를 위한 인덱스
i2=i3=i5=0
# 첫 번째 못생긴 수 1의 2배, 3배, 5배한 값으로 초기화
next2,next3,next5=2,3,5
for i in range(1,n):
# 2, 3, 5를 곱한 것 중 가장 작은 수를 선택함
ugly[i] = min(next2,next3,next5)
if ugly[i]==next2:
i2+=1
next2 = ugly[i2]*2
if ugly[i]==next3:
i3+=1
next3=ugly[i3]*3
if ugly[i]==next5:
i5+=1
next5=ugly[i5]*5
print(ugly[n-1])

후기

  • i2, i3, i5를 활용하는 방법이 인상적이었다.

 

출처

이것이 취업을 위한 코딩테스트다 with 파이썬