Solution to LeetCode 100 Same Tree, LeetCode 101 Symmetric Tree, and LeetCode 572 Subtree of Another Tree.
LeetCode 100
Same Tree (Easy) [link]
Same idea as LC101, but check whether they are the same rather than checking whether they are mirror.
1] Recursive solution. DFS. Time complexity O(min(n,m)). Space complexity O(min(m,n)).
# 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 isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if p == None and q == None:
return True
elif p == None or q == None or q.val != p.val:
return False
else:
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
We don’t need to define another recursion function within isSameTree
, because isSameTree
also works on smaller subtrees.
2] Iterative solution using Queue. BFS. Time complexity O(min(n,m)). Space complexity O(min(m,n)).
# 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 isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
que = deque()
que.append(p)
que.append(q)
while que:
first = que.popleft()
second = que.popleft()
if not first and not second:
continue
if not first or not second or first.val != second.val:
return False
que.append(first.left)
que.append(second.left)
que.append(first.right)
que.append(second.right)
return True
3] Iterative solution using stack. Time complexity O(min(n,m)). Space complexity O(min(m,n)).
# 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 isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
stack = []
stack.append(p)
stack.append(q)
while stack:
first = stack.pop()
second = stack.pop()
if not first and not second:
continue
if not first or not second or first.val != second.val:
return False
stack.append(first.left)
stack.append(second.left)
stack.append(first.right)
stack.append(second.right)
return True
LeetCode 101
Symmetric Tree (Easy) [link]
1] Recursive solution. In the following cases, we return False: 1) left != None and right == None
2) left == None and right != None
3) left.val != right.val
. we return True if left == None and right == None
. Those are the stopping criteria. Otherwise, we return True. When comparing the children in the same level, we return True if all of the following are satisfied 1) left.left == right.right
2) left.right == right.left
. Otherwise, we return False. Time complexity O(n). Space complexity O(n).
# 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 isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return False
def compare(left,right):
if left == None and right == None:
return True
elif left == None or right == None or left.val != right.val:
return False
outside = compare(left.left, right.right)
inside = compare(left.right, right.left)
return outside and inside
return compare(root.left, root.right)
There has to be a function defined within isSymmetric
because we are not comparing two children of a node, rather, we are comparing between the children belonging to different parent.
2] Iterative solution using Queue. Time complexity O(n). Space complexity O(n).
# 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 isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return False
que = deque()
que.append(root.left)
que.append(root.right)
while que:
left = que.popleft()
right = que.popleft()
if not left and not right:
continue
if not left or not right or left.val != right.val:
return False
que.append(left.left)
que.append(right.right)
que.append(left.right)
que.append(right.left)
return True
3] Iterative solution using Stack. Same idea as [2]. Time complexity O(n). Space complexity O(n).
# 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 isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return False
stack = []
stack.append(root.left)
stack.append(root.right)
while stack:
left = stack.pop()
right = stack.pop()
if not left and not right:
continue
if not left or not right or left.val != right.val:
return False
stack.append(left.left)
stack.append(right.right)
stack.append(left.right)
stack.append(right.left)
return True
LeetCode 572
Subtree of Another Tree (Easy) [link]
We check whether subRoot
is the same as any subtree of the root
. The checking method is the same as in LC 100. Here we check every subtree of root
with subRoot
. Note that both isSubtree
and isSameTree
functions are recursive function, so both need stopping criteria. Time complexity O(pq). Space complexity O(max(p,q)).
# 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: TreeNode, subRoot: TreeNode) -> bool:
def isSameTree(p, q):
if not p and not q:
return True
elif not p or not q:
return False
return p.val == q.val and isSameTree(p.left, q.left) and isSameTree(p.right, q.right)
if not root and not subRoot:
return True
elif not root or not subRoot:
return False
return isSameTree(root, subRoot) or self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot