자료구조, 알고리즘
하노이의탑(yield)
empus
2024. 1. 9. 15:04
프로그래머스의 하노이의 탑 문제
import copy
def solution(n):
answer = [[1,3]]
for i in range(n-1):
temp=copy.deepcopy(answer)
for j in range(len(temp)):
for k in range(len(temp[0])):
if temp[j][k]==1:temp[j][k]=2
elif temp[j][k]==2:temp[j][k]=1
for j in range(len(answer)):
for k in range(len(answer[0])):
if answer[j][k]==2:answer[j][k]=3
elif answer[j][k]==3:answer[j][k]=2
answer.append([1,3])
answer+=temp
return answer
아이디어는 최종적으로 모두 3번기둥으로 옮겨야 하므로 n층의 탑일 경우 n-1층의 탑을 옮기는 과정을 2번기둥으로 옮기는 과정으로 바꾼 후 2번기둥을 모두 3번기둥으로 옮기면 되므로 n-1의 답을 2,3을 바꾼 후(3번기둥 대신 2번기둥으로 옮기기) [1,3]을 더한 후(가장 큰 층을 3번기둥으로) n-1의 답을 1,2를 바꾼 값(2번기둥에서 3번기둥으로 이동) 을 더해주는 것이다.
deepcopy를 사용해서 list를 복사한 후 값을 변경해 더해주었다.
다른 사람의 풀이중 인상적이었던 풀이는 yield를 사용한 풀이로
def hanoi(n):
def _hanoi(m, s, b, d):
if m == 1:
yield [s, d]
else:
yield from _hanoi(m-1, s, d, b)
yield [s, d]
yield from _hanoi(m-1, b, s, d)
ans = list(_hanoi(n, 1, 2, 3))
return ans
아이디어는 똑같이 n-1번째의 답에서 기둥을 바꾸고 [1,3]을 더하는 것이지만 훨씬 깔끔하고 보기 편하다.
yield의 기능은 순차적으로 출력하는 것으로
def simple_generator():
yield 1
yield 2
yield 3
for value in simple_generator():
print(value)
1
2
3
이런 식으로 사용할 수 있고 list를 사용하면
print(list(simple_generator()))
#[1,2,3]
이렇게 사용할 수 있다.
내가 작성한 코드와의 차이는
시간복잡도는 둘 다 O(2^n)이지만 공간복잡도는 내가 작성한 코드는 deepcopy를 사용해 매 반복마다 전체 리스트를 복사하므로 최악의 경우 O(2^n)에 가깝지만 yield를 사용할 시 재귀 함수의 최대 깊이인 O(n)이 된다.