어느 트리의 인오더와 포스트오더의 출력물을 가지고 트리를 추정하여 preorder로 출력해야하는 문제이다.
포스트오더의 맨뒤가 항상 루트노드이고 인오더는 그 루트노드를 기준으로 좌우 노드를 구분할 수 있다는 힌트를 이용해야한다.
재귀를 시작하기전에 주어진 인오더 노드들의 위치가 몇번째인지 인덱스를 node_index변수에 기록해둔다. 사용할 재귀함수는 4가지 인자를 받는데 아래와 같다.
1. 현재 사이클에서 인오더의 시작노드 인덱스.
2. 현재 사이클에서 인오더의 끝노드 인덱스.
3. 현재 사이클에서 포스트오더의 시작노드 인덱스.
4. 현재 사이클에서 포스트오더의 끝노드 인덱스.
재귀 종료조건은 인오더나 포스트오더의 시작인덱스가 끝노드 인덱스를 초과하면 종료하도록한다.
매 사이클마다 포스트오더 끝인덱스는 항상 루트노드이므로 이를기준으로 인오더의 좌우의 기준을 잡아 왼쪽노드 크기와 오른쪽 노드의 크기를 구한다. 그리고 왼쪽노드 사이클과 오른쪽 노드 사이클을 돌려준다.
import sys
sys.setrecursionlimit(10**9)
n = int(input())
inorder = [*map(int,input().split(' '))]
postorder = [*map(int,input().split(' '))]
node_index = dict()
for i in range(len(inorder)):
node_index[inorder[i]] = i
def cycle(in_start, in_end, post_start, post_end):
if in_start > in_end or post_start > post_end:
return
root = postorder[post_end]
# 다음 재귀로 넘길 왼쪽 노드사이즈
left_size = node_index[root] - in_start
# 다음 재귀로 넘길 오른쪽 노드사이즈
right_size = in_end - node_index[root]
print(root, end=' ')
# 왼쪽 사이클
cycle(in_start, node_index[root] - 1, post_start, post_start + left_size - 1)
# 오른쪽 사이클
cycle(node_index[root] + 1, in_end, post_end - right_size, post_end - 1)
cycle(0, n - 1, 0, n - 1)