572. Subtree of Another Tree
Problem
Given the roots of two binary trees root and subRoot, return true if there is a subtree of root with the same structure and node values of subRoot and false otherwise.
A subtree of a binary tree tree is a tree that consists of a node in tree and all of this node’s descendants. The tree tree could also be considered as a subtree of itself.
https://leetcode.com/problems/subtree-of-another-tree/
Example 1:

Input:
root = [3,4,5,1,2], subRoot = [4,1,2]
Output:true
Example 2:

Input:
root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
Output:false
Constraints:
- The number of nodes in the
roottree is in the range[1, 2000]. - The number of nodes in the
subRoottree is in the range[1, 1000]. -10⁴ <= root.val <= 10⁴-10⁴ <= subRoot.val <= 10⁴
Test Cases
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:import pytest
from solution import Solution
from utils import build_tree, TreeNode
null = None
@pytest.mark.parametrize('root, subRoot, expected', [
([3,4,5,1,2], [4,1,2], True),
([3,4,5,1,2,null,null,null,null,0], [4,1,2], False),
])
class Test:
def test_solution(self, root, subRoot, expected):
sol = Solution()
root = build_tree(root)
subRoot = build_tree(subRoot)
assert sol.isSubtree(root, subRoot) == expected
Thoughts
先看比较两颗二叉树是否相等。同时按同样的顺序遍历两颗树,只要出现一边有节点另一边是空,或者两边节点的值不同,就不相等。
比如用前序遍历(NLR)。可以用栈替代递归,给两个树各维持一个栈,或者用一个栈但每次把两棵树的节点打包入栈。
要判断 subRoot 是否是 root 的子树,先判断 root 跟 subRoot 是否相等,不相等的话再递归判定 subRoot 是不是 root.left 或 root.right 的子树。同样可以用栈替代递归,对 root 做 NLR 遍历,遍历到任何一个节点时,判断以该节点为根的子树是否跟 subRoot 相等。
设 root 和 subRoot 的节点数分别是 n 和 m,则时间复杂度为 O(n * m)。
Code
from typing import Optional
from utils import TreeNode
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
stack = []
while root or stack:
if root:
if self._is_same(root, subRoot):
return True
stack.append(root)
root = root.left
else:
root = stack.pop().right
return False
def _is_same(self, root1: TreeNode|None, root2: TreeNode|None) -> bool:
stack = []
while root1 or root2 or stack:
if (not not root1) != (not not root2):
return False
elif root1:
if root1.val != root2.val:
return False
stack.append((root1, root2))
root1 = root1.left
root2 = root2.left
elif stack:
root1, root2 = stack.pop()
root1 = root1.right
root2 = root2.right
return True
似乎用栈并不比直接用递归快。
评论需要 JavaScript。