Two trees are flip equivalent if we can make them identical by swapping the left and right children of some nodes. At each node, the subtrees either match directly (left with left, right with right) or match when flipped (left with right, right with left). We recursively check both possibilities.
null, return true only if both are null.false.true if either scenario succeeds.# 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 flipEquiv(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> bool:
if not root1 or not root2:
return not root1 and not root2
if root1.val != root2.val:
return False
return (
self.flipEquiv(root1.left, root2.left) and
self.flipEquiv(root1.right, root2.right) or
self.flipEquiv(root1.left, root2.right) and
self.flipEquiv(root1.right, root2.left)
)We can solve this iteratively using a queue to process node pairs level by level. For each pair of nodes, we check if their values match. Then we determine whether to compare children directly or in flipped order by checking which pairing makes the left children's values match.
(root1, root2).null, check that both are null. If not, return false.false.null, pair children directly. Otherwise, pair them in flipped order.true if all pairs are processed successfully.# 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 flipEquiv(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> bool:
q = deque([(root1, root2)])
while q:
node1, node2 = q.popleft()
if not node1 or not node2:
if node1 != node2:
return False
continue
if node1.val != node2.val:
return False
if ((node1.right and node2.right and
node1.right.val == node2.right.val) or
(not node1.right and not node2.right)
):
q.append((node1.left, node2.left))
q.append((node1.right, node2.right))
else:
q.append((node1.left, node2.right))
q.append((node1.right, node2.left))
return TrueThis is the iterative version of the recursive DFS approach, using an explicit stack instead of the call stack. We process node pairs from the stack, checking values and pushing child pairs in the appropriate order (direct or flipped).
(root1, root2).null, verify both are null. If not, return false.false.null or same value), push direct pairs. Otherwise, push flipped pairs.true if all pairs are processed successfully.# 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 flipEquiv(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> bool:
stack = [(root1, root2)]
while stack:
node1, node2 = stack.pop()
if not node1 or not node2:
if node1 != node2:
return False
continue
if node1.val != node2.val:
return False
if ((node1.left and node2.left and
node1.left.val == node2.left.val) or
(not node1.left and not node2.left)
):
stack.append((node1.left, node2.left))
stack.append((node1.right, node2.right))
else:
stack.append((node1.left, node2.right))
stack.append((node1.right, node2.left))
return True