Given the root
of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center).
Example 1:
Input: root = [1,2,2,3,4,4,3] Output: true
Example 2:
Input: root = [1,2,2,null,3,null,3] Output: false
Constraints:
[1, 1000]
.-100 <= Node.val <= 100
Follow up: Could you solve it both recursively and iteratively?
The core challenge of this problem is to determine if a binary tree is symmetric around its center. This means that the left subtree should be a mirror reflection of the right subtree.
Common applications of this problem include validating the structure of data in hierarchical systems and ensuring balanced data distribution in tree-based structures.
Potential pitfalls include misunderstanding the symmetry concept and not handling null nodes correctly.
To solve this problem, we can use two main approaches: recursive and iterative.
In the recursive approach, we define a helper function that checks if two trees are mirror images of each other. This function will be called with the left and right children of the root node.
Steps:
In the iterative approach, we use a queue to perform a level-order traversal and compare nodes at each level.
Steps:
def is_symmetric(root):
def is_mirror(left, right):
# If both nodes are null, they are mirrors
if not left and not right:
return True
# If one of the nodes is null, they are not mirrors
if not left or not right:
return False
# Check if the current nodes are equal and their subtrees are mirrors
return (left.val == right.val and
is_mirror(left.left, right.right) and
is_mirror(left.right, right.left))
# Start the recursion with the left and right children of the root
return is_mirror(root.left, root.right)
from collections import deque
def is_symmetric(root):
if not root:
return True
queue = deque([(root.left, root.right)])
while queue:
left, right = queue.popleft()
# If both nodes are null, continue
if not left and not right:
continue
# If one of the nodes is null, they are not mirrors
if not left or not right:
return False
# If the values are not equal, they are not mirrors
if left.val != right.val:
return False
# Add the children in the order that ensures symmetry
queue.append((left.left, right.right))
queue.append((left.right, right.left))
return True
For both the recursive and iterative approaches, the time complexity is O(n), where n is the number of nodes in the tree. This is because we visit each node once.
The space complexity for the recursive approach is O(h), where h is the height of the tree, due to the recursion stack. For the iterative approach, the space complexity is O(n) due to the queue.
Consider the following edge cases:
To test the solution comprehensively, consider the following test cases:
def test_is_symmetric():
# Test case 1: Symmetric tree
root1 = TreeNode(1)
root1.left = TreeNode(2)
root1.right = TreeNode(2)
root1.left.left = TreeNode(3)
root1.left.right = TreeNode(4)
root1.right.left = TreeNode(4)
root1.right.right = TreeNode(3)
assert is_symmetric(root1) == True
# Test case 2: Asymmetric tree
root2 = TreeNode(1)
root2.left = TreeNode(2)
root2.right = TreeNode(2)
root2.left.right = TreeNode(3)
root2.right.right = TreeNode(3)
assert is_symmetric(root2) == False
# Test case 3: Single node tree
root3 = TreeNode(1)
assert is_symmetric(root3) == True
# Test case 4: Empty tree
root4 = None
assert is_symmetric(root4) == True
test_is_symmetric()
When approaching such problems, consider the following tips:
Understanding and solving the symmetric tree problem helps in grasping tree traversal techniques and recursion. Practice with different tree problems to improve your problem-solving skills.