Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python으로 이진 트리 같은 레벨의 리프 노드 합계 곱 구하기

문제 개요

이진 트리(Binary Tree)가 주어졌을 때 다음 두 가지 작업을 수행해야 합니다.

  • 각 레벨(level)에 리프 노드가 존재하면 해당 레벨에 있는 모든 리프 노드 값의 합을 구합니다. 리프 노드가 없는 레벨은 무시합니다.
  • 구한 모든 합계를 서로 곱한 결과를 반환합니다.

예를 들어 아래와 같은 이진 트리가 입력으로 주어진다고 가정해 보겠습니다.

Python으로 이진 트리 같은 레벨의 리프 노드 합계 곱 구하기

이 경우 출력값은 270입니다. 첫 번째와 두 번째 레벨에는 리프 노드가 없고, 세 번째 레벨에는 리프 노드 9 하나만 존재합니다. 마지막 레벨에는 2, 12, 5, 11 네 개의 리프 노드가 있습니다. 따라서 결과는 9 × (2 + 12 + 5 + 11) = 270이 됩니다.

접근 방법

이 문제는 큐(queue)를 이용한 BFS(너비 우선 탐색) 방식의 레벨 순회(level-order traversal)로 해결할 수 있습니다. 단계별 알고리즘은 다음과 같습니다.

  1. 루트가 null이면 0을 반환합니다.
  2. 결과를 저장할 변수 res를 1로 초기화합니다.
  3. 큐를 생성하고 루트 노드를 삽입합니다.
  4. 큐가 빌 때까지 다음 과정을 반복합니다.
    • 현재 큐의 크기를 no_of_nodes에 저장하고, 크기가 0이면 반복을 종료합니다.
    • sum_level은 0, found_leaf는 False로 초기화합니다.
    • no_of_nodes가 0보다 큰 동안 큐에서 노드를 하나씩 꺼냅니다.
    • 꺼낸 노드가 리프 노드라면 found_leaf를 True로 설정하고 노드 값을 sum_level에 더합니다.
    • 현재 노드에 왼쪽 또는 오른쪽 자식이 있으면 큐의 끝에 추가합니다.
  5. 해당 레벨에서 리프 노드를 발견했다면 res에 sum_level을 곱합니다.
  6. 모든 레벨의 처리가 끝나면 res를 반환합니다.

구현 예제

아래 파이썬 코드를 통해 실제 구현 방법을 확인해 보겠습니다.

class TreeNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None

def isLeaf(root):
    return (not root.left and not root.right)

def find_res(root):
    if not root:
        return 0
    res = 1
    que = []
    que.append(root)
    while True:
        no_of_nodes = len(que)
        if no_of_nodes == 0:
            break
        sum_level = 0
        found_leaf = False
        while no_of_nodes > 0:
            curr_node = que[0]
            if isLeaf(curr_node):
                found_leaf = True
                sum_level += curr_node.data
            que.pop(0)
            if curr_node.left != None:
                que.append(curr_node.left)
            if curr_node.right != None:
                que.append(curr_node.right)
            no_of_nodes -= 1
        if found_leaf:
            res *= sum_level
    return res

root = TreeNode(8)
root.left = TreeNode(8)
root.right = TreeNode(6)
root.left.right = TreeNode(7)
root.left.left = TreeNode(9)
root.left.right.left = TreeNode(2)
root.left.right.right = TreeNode(12)
root.right.right = TreeNode(10)
root.right.right.left = TreeNode(5)
root.right.right.right = TreeNode(11)
print(find_res(root))

입력

root = TreeNode(8)
root.left = TreeNode(8)
root.right = TreeNode(6)
root.left.right = TreeNode(7)
root.left.left = TreeNode(9)
root.left.right.left = TreeNode(2)
root.left.right.right = TreeNode(12)
root.right.right = TreeNode(10)
root.right.right.left = TreeNode(5)
root.right.right.right = TreeNode(11)

출력

270

복잡도 분석

이 알고리즘은 트리의 모든 노드를 정확히 한 번씩 방문하므로 시간 복잡도는 O(n)입니다. 큐에는 한 번에 최대 한 레벨의 노드만 저장되므로 공간 복잡도는 트리의 최대 폭 w에 비례하는 O(w)입니다.