문제를 읽어보면 깊이가 K인 완전 이진 트리가 주어지고, 상근이는 중위순회 방식(왼쪽-> 루트 -> 오른쪽 순)으로 트리를 순회합니다.
이런 환경에서 상근이가 방문한 빌딩 번호가 순서대로 주어질 때, 완전 이진트리를 역으로 유추해 각 레벨에 있는 빌딩의 번호를 출력하는 문제입니다.
✅ 접근 방식
완전 이진 트리라는 점, 상근이가 중위순회를 한다는 것, 그리고 가장 마지막 레벨을 제외한 모든 집은 왼쪽 자식과 오른쪽 자식을 갖는다는 점이 문제의 키 포인트였습니다.
조건1) 중위순회 : 중위순회를 하기 때문에 상근이가 방문한 빌딩의 순서가 (왼쪽노드)->(루트)->(오른쪽노드)로 배치됩니다. 조건2) 완전 이진 트리 & 가장 마지막 레벨을 제외한 노드가 왼쪽 자식과 오른쪽 자식을 갖는다 : 완전 이진 트리는 레벨이 k일때 k-1까지는 포화이진트리이고, 레벨 k부터는 왼쪽부터 노드가 순서대로 채우어진 이진트리입니다. 근데 이때 문제에서 마지막 레벨 k를 제외한 노드가 왼쪽과 오른쪽 자식을 가진다고 하였으므로 사실상 그냥 완전 이진 트리가 아니라 포화 이진 트리가 되게됩니다.
따라서 조건1), 조건2) 때문에 상근이의 방문한 빌딩 번호 리스트의 딱 중간이 루트가 됩니다.
이후 각 레벨별 노드를 출력해줍니다. separation(arr[:mid], depth + 1) -> separation(arr[mid + 1:], depth + 1) 순으로 호출했기 때문에 출력은 왼쪽에서부터 오른쪽 순서대로 출력이 됩니다.
✅ 최종 코드
# 완전 이진 트리
import sys
k = int(sys.stdin.readline())
arr = list(map(int, sys.stdin.readline().split()))
levels = [[] for _ in range(k)]
def separation(arr, depth):
if len(arr) == 1: # 요소가 하나밖에 없을 때
levels[depth].extend(arr)
return
mid = len(arr) // 2
levels[depth].append(arr[mid]) # 중간값=루트만 depth 레벨이므로 levels[depth]에 넣어줌
separation(arr[:mid], depth + 1)
separation(arr[mid + 1:], depth + 1)
separation(arr, 0)
for level in levels:
for i in level:
print(i, end=" ")
print()
❇️ 코멘트
배열의 중간에 있는 값에 접근할 때는 mid = len(arr)//2로 두고, arr[mid]로 접근하면 된다는걸 알게되었습니다.
extend 함수 = extend는 리스트를 리스트안으로 넣을 때 리스트의 원소를 꺼내서 넣어줍니다.
접근 방식을 파악해도 구현이 생각보다 쉽지 않은 문제였습니다. -> level값을 인자로 주면서 재귀를 이용하여 푸는 방법을 생각할 줄 알아야 했습니다.