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

파이썬으로 이진 트리가 대칭인지 판별하는 방법

대칭 이진 트리란?

하나의 이진 트리가 주어졌을 때, 해당 트리가 대칭(symmetric) 트리인지 판별해야 합니다. 트리를 좌우로 뒤집은 거울상(미러 이미지)이 원래 트리와 완전히 동일할 때, 그 트리를 대칭 트리라고 부릅니다.

예를 들어 아래 두 트리 중 첫 번째 트리는 대칭이지만, 두 번째 트리는 일부 노드의 위치가 어긋나 있어 대칭이 아닙니다.

파이썬으로 이진 트리가 대칭인지 판별하는 방법

해결 접근 방법

대칭 여부는 루트의 왼쪽 서브트리와 오른쪽 서브트리를 서로 미러링하며 비교하는 재귀 방식으로 해결할 수 있습니다. 구체적인 단계는 다음과 같습니다.

  • solve(root, root) 형태로 함수를 호출한 뒤, 이후 단계들을 재귀적으로 수행합니다.
  • 두 노드(node1, node2)가 모두 비어 있다면 true를 반환합니다.
  • 둘 중 하나만 비어 있다면 false를 반환합니다.
  • node1의 값과 node2의 값이 같고, solve(node1.left, node2.right)와 solve(node1.right, node2.left)가 모두 참일 때 true를 반환합니다.

핵심은 왼쪽 자식과 상대편의 오른쪽 자식을, 오른쪽 자식과 상대편의 왼쪽 자식을 교차 비교한다는 점입니다. 이렇게 하면 트리 전체에서 거울상 관계가 유지되는지 검증할 수 있습니다.

파이썬 구현 예제

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

def insert(temp, data):
    que = []
    que.append(temp)
    while len(que):
        temp = que[0]
        que.pop(0)
        if not temp.left:
            if data is not None:
                temp.left = TreeNode(data)
            else:
                temp.left = TreeNode(0)
            break
        else:
            que.append(temp.left)
        if not temp.right:
            if data is not None:
                temp.right = TreeNode(data)
            else:
                temp.right = TreeNode(0)
            break
        else:
            que.append(temp.right)

def make_tree(elements):
    Tree = TreeNode(elements[0])
    for element in elements[1:]:
        insert(Tree, element)
    return Tree

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        return self.solve(root, root)

    def solve(self, node1, node2):
        if not node1 and not node2:
            return True
        if not node1 or not node2:
            return False
        return (node1.data == node2.data and
                self.solve(node1.left, node2.right) and
                self.solve(node1.right, node2.left))

tree1 = make_tree([1, 2, 2, 3, 4, 4, 3])
tree2 = make_tree([1, 2, 2, 3, 4, None, 3])

ob1 = Solution()
print(ob1.isSymmetric(tree1))
print(ob1.isSymmetric(tree2))

입력

tree1 = make_tree([1, 2, 2, 3, 4, 4, 3])
tree2 = make_tree([1, 2, 2, 3, 4, None, 3])

출력

True
False

복잡도 분석

시간 복잡도: O(n) — 트리의 모든 노드를 한 번씩 방문합니다.
공간 복잡도: O(h) — 재귀 호출 스택의 깊이는 트리의 높이(h)에 비례하며, 최악의 경우(편향된 트리) O(n)까지 증가할 수 있습니다.