이미지 출처: https://www.acmicpc.net/problem/2250
레벨의 너비는 해당 레벨의 노드 중 가장 왼쪽에 있는 노드와 가장 오른쪽에 있는 노드의 차 + 1 이다.
임의의 이진트리가 입력으로 주어질 때 너비가 가장 넓은 레벨과 그 레벨의 너비를 출력해라.
⏱ 노드의 개수 N (1≤ N ≤ 10000)
해당 문제는 알고리즘 자체는 어렵지 않았지만, 저장해야 할 값들이 많아서 헷갈렸다.
각 레벨(깊이)의 너비와 해당 레벨 값을 구하기 위해서
dict를 활용하여 입력을 트리로 만들었다.
tree = {1 : [2,3]} # root : [left_node, right_node]
노드를 살펴보면, 8→ 4 → 2 → 14 → 9 → 18 → .. 순으로 idx가 1부터 N까지 매겨진다.
가장 왼쪽에 있는 노드 부터 가장 오른쪽에 있는 노드까지 오른쪽으로 하나씩 순차적으로 탐색하며 아래 값을 구한다.
def in_order(key):
global cur
if tree[key][0] != -1: # 왼쪽 노드가 있을 때
level[tree[key][0]] = level[key] + 1 # 왼쪽 노드의 레벨은 현재 레벨+1
in_order(tree[key][0])
cur += 1 # 노드 방문하면서 1 부터 N까지 idx 증가
if level_min[level[key]] > cur:
level_min[level[key]] = cur # 현재 레벨의 가장 왼쪽 노드 idx 갱신
if level_max[level[key]] < cur:
level_max[level[key]] = cur
if tree[key][1] != -1:
level[tree[key][1]] = level[key] + 1
in_order(tree[key][1])
return
n = int(input())
parentNode = [-1]*(n+1)
tree = {}
root = 0
for _ in range(n): # 1) 트리 형태 만들기
v, left, right = map(int, input().split(' '))
tree[v] = [left, right]
if left != -1:
parentNode[left] = v
if right != -1:
parentNode[right] = v
for i in range(1, n+1): # 2) 루트 노드 찾기
if parentNode[i] == -1:
root = i
level_min = [n]*(n+1) # 각 레벨의 최소, 최대 idx 저장
level_max = [0]*(n+1)
level = [0]*(n+1)
level[root] = 1
cur = 0
def in_order(key): # 3) 중위 순회
global cur
if tree[key][0] != -1:
level[tree[key][0]] = level[key] + 1
in_order(tree[key][0])
cur += 1
if level_min[level[key]] > cur:
level_min[level[key]] = cur
if level_max[level[key]] < cur:
level_max[level[key]] = cur
if tree[key][1] != -1:
level[tree[key][1]] = level[key] + 1
in_order(tree[key][1])
return
in_order(root)
result = 0
result_idx = 0
for i in range(1, n+1): # 4) 차이 찾기
diff = level_max[i]-level_min[i]+1
if result < diff:
result = diff
result_idx = i
print(result_idx, result)