문제 링크
문제 설명
주어진 두 개의 이진 트리 root
와 subRoot
가 있을 때, root
트리의 어떤 서브트리가 subRoot
와 동일한 구조와 값을 가지고 있는지를 확인하는 함수를 작성하세요. 서브트리는 트리의 어떤 노드와 그 노드의 모든 자손으로 구성된 트리를 의미합니다. 주어진 트리 root
가 자신을 서브트리로 간주할 수도 있습니다.
예제
- 예제 1
- 입력:
root = [3,4,5,1,2]
,subRoot = [4,1,2]
- 출력:
true
- 설명:
root
트리에서 4를 루트로 하는 서브트리는subRoot
와 동일한 구조와 값을 가집니다.
- 입력:
- 예제 2
- 입력:
root = [3,4,5,1,2,null,null,null,null,0]
,subRoot = [4,1,2]
- 출력:
false
- 설명:
root
의 어떤 서브트리도subRoot
와 동일하지 않으므로false
를 반환합니다.
- 입력:
풀이 전략
이 문제를 해결하기 위한 일반적인 접근 방법은 다음과 같습니다:
- 서브트리 탐색:
root
트리의 각 노드를 탐색하며, 각 노드가subRoot
의 루트가 될 수 있는지 확인합니다.
- 트리 비교:
- 어떤 노드가
subRoot
의 루트와 같다고 가정할 때, 그 서브트리와subRoot
가 동일한지 확인하는 함수를 호출합니다.
- 어떤 노드가
- 재귀적 접근:
- 두 트리의 노드가 동일한지 확인하기 위해 재귀적으로 비교하는 방법을 사용할 수 있습니다.
코드 분석
코드 구현
class Solution:
def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
if not subRoot:
return True # 빈 서브트리는 항상 존재
if not root:
return False # root가 None인데 subRoot가 있는 경우
if self.isSameTree(root, subRoot):
return True # 현재 root 노드가 subRoot와 같은 경우
# 왼쪽과 오른쪽 서브트리에서 탐색
return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if not p and not q:
return True # 두 노드가 모두 None인 경우
if not p or not q:
return False # 하나만 None인 경우
if p.val != q.val:
return False # 두 노드의 값이 다를 경우
# 왼쪽 서브트리와 오른쪽 서브트리 비교
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
isSubtree
함수:subRoot
가 비어있으면 항상True
를 반환합니다.root
가 비어있으면False
를 반환합니다.- 현재
root
노드와subRoot
가 동일한지를isSameTree
함수를 통해 확인합니다. - 동일하지 않은 경우, 왼쪽과 오른쪽 서브트리에서 재귀적으로
isSubtree
를 호출하여 탐색합니다.
isSameTree
함수:- 두 노드가 모두
None
이면True
를 반환합니다. - 한 쪽만
None
인 경우False
를 반환합니다. - 두 노드의 값이 다르면
False
를 반환합니다. - 두 서브트리를 재귀적으로 비교합니다.
- 두 노드가 모두
- 시간 복잡도: (O(m \cdot n)) -
root
의 모든 노드에 대해subRoot
와 비교하는 데 걸리는 시간, 여기서 (m)은root
의 노드 수, (n)은subRoot
의 노드 수입니다. - 공간 복잡도: (O(h)) - 재귀 호출 스택의 깊이는 트리의 높이에 비례합니다. 최악의 경우 (h)는 (O(m))일 수 있습니다.
요약
- 주어진 두 이진 트리의 서브트리 비교 문제로,
root
의 각 노드에 대해subRoot
와의 동일성을 확인하는 방식으로 접근합니다. - 재귀적으로 트리를 비교하는 방법을 사용하며, 시간 복잡도는 (O(m \cdot n))입니다.