# Solution 1
def isSubtree(root: Optional[TreeNode], subroot: Optional[TreeNode]) -> bool:
def helper_equal(root, subroot):
if not (root and subroot):
return root is subroot
return(root.val==subroot.val and
helper_equal(root.left, subroot.left) and
helper_equal(root.right, subroot.right))
def helper_is_subtree(root, subroot):
if helper_equal(root, subroot):
return True
if not root:
return(False)
return(helper_is_subtree(root.left, subroot) or helper_is_subtree(root.right, subroot))
return(helper_is_subtree(root, subroot))
# Solution 2
from hashlib import sha256
def isSubtree(root: Optional[TreeNode], subroot: Optional[TreeNode]) -> bool:
def hash_(x):
S = sha256()
S.update(x)
return S.hexdigest()
def merkle(node):
if not node:
return '#'
m_left = merkle(node.left)
m_right = merkle(node.right)
node.merkle = hash_(m_left + str(node.val) + m_right)
return node.merkle
merkle(root)
merkle(subroot)
def dfs(node):
if not node:
return False
return (node.merkle == subroot.merkle or
dfs(node.left) or dfs(node.right))
return dfs(root)