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

파이썬으로 이진 트리 노드 삭제 후 남은 포리스트의 루트 찾기


이진 트리의 루트 노드가 주어지고, 트리의 각 노드는 고유한 값을 가진다고 가정해 보겠습니다. 이때 to_delete 배열에 포함된 값을 가진 모든 노드를 삭제하면, 트리는 여러 개의 분리된 트리 집합, 즉 포리스트(forest)가 됩니다. 우리가 해야 할 일은 이 남은 포리스트를 구성하는 각 트리의 루트 노드들을 찾아내는 것입니다.

예를 들어 다음과 같은 이진 트리가 있다고 합시다.

파이썬으로 이진 트리 노드 삭제 후 남은 포리스트의 루트 찾기

만약 삭제할 값 배열 to_delete가 [3, 5]라면, 노드 3과 5가 제거된 후 결과는 다음과 같습니다.

파이썬으로 이진 트리 노드 삭제 후 남은 포리스트의 루트 찾기

해결 접근 방식

이 문제는 재귀적 순회(DFS)를 활용하면 깔끔하게 해결할 수 있습니다. 핵심 아이디어는 다음과 같습니다.

  • 결과를 저장할 배열 res를 정의합니다.
  • solve() 메서드를 정의합니다. 이 메서드는 현재 노드(node), 삭제 대상 배열(to_delete), 그리고 해당 노드가 루트인지 여부를 나타내는 불리언 값(is_root)을 매개변수로 받으며, 다음과 같이 동작합니다.
  • 노드가 null이면 null을 반환합니다.
  • 현재 노드의 값이 to_delete 배열에 존재하는지 확인하여 flag를 설정합니다.
  • flag가 false이고 is_root가 true라면, 현재 노드는 새로운 트리의 루트이므로 res에 추가합니다.
  • 왼쪽 자식과 오른쪽 자식에 대해 solve()를 재귀 호출합니다. 이때 부모 노드가 삭제되는 경우(flag가 true) 자식들은 새로운 루트 후보가 되므로, flag 값을 is_root 인자로 전달합니다.
  • 현재 노드가 삭제 대상이라면 None을 반환하고, 그렇지 않으면 노드 자신을 반환합니다.
  • 메인 메서드에서 solve(root, to_delete, True) 형태로 호출하여 전체 순회를 시작합니다.

이제 실제 구현 예제를 통해 더 자세히 살펴보겠습니다.

예제 코드

class Solution(object):
   def delNodes(self, root, to_delete):
      """
      :type root: TreeNode
      :type to_delete: List[int]
      :rtype: List[TreeNode]
    """
      to_delete = set(to_delete)
      self.res = []
      self.solve(root,to_delete,True)
      return self.res
   def solve(self,node,to_delete,is_root):
      if not node:
         return None
      flag = node.val in to_delete
      if not flag and is_root:
         self.res.append(node)
      node.left = self.solve(node.left,to_delete,flag)
      node.right = self.solve(node.right,to_delete,flag)
      return None if flag else node

위 코드에서 to_delete 리스트를 set으로 변환한 점에 주목하세요. 이렇게 하면 특정 값이 삭제 목록에 있는지 확인하는 연산의 시간 복잡도가 O(n)에서 O(1)로 개선되어 전체 알고리즘의 효율이 크게 향상됩니다.

입력

[1,2,3,4,5,6,7]
[3,5]

출력

[[1,2,null,4],[6],[7]]

실행 결과를 보면, 값 3과 5를 가진 노드가 삭제된 후 세 개의 독립적인 트리 [1,2,null,4], [6], [7]의 루트들이 올바르게 반환된 것을 확인할 수 있습니다. 이 알고리즘의 시간 복잡도는 트리의 모든 노드를 한 번씩 방문하므로 O(N)이며, 공간 복잡도 역시 재귀 호출 스택 깊이 기준으로 O(N)입니다.