LeetCode 第 101 题「对称二叉树」
字数 1538 2025-10-25 17:25:28
好的,我们这次来详细讲解 LeetCode 第 101 题「对称二叉树」。
这道题非常经典,能很好地帮助我们理解递归和树的结构。
1. 题目描述
题目:给你一个二叉树的根节点 root,检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
1
/ \
2 2
/ \ / \
3 4 4 3
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
1
/ \
2 2
\ \
3 3
注意:空树也被视为对称。
2. 题意理解
“轴对称”意味着:
- 左子树和右子树互为镜像。
- 镜像的条件:
- 两个根节点值相同。
- 每个树的右子树与另一个树的左子树对称。
- 每个树的左子树与另一个树的右子树对称。
换句话说,我们想象在根节点处放一面镜子,左子树翻转后应该和右子树完全一样。
3. 递归思路分解
3.1 递归函数设计
我们设计一个辅助函数:
def isMirror(t1, t2) -> bool:
它判断两棵树 t1 和 t2 是否互为镜像。
3.2 递归终止条件
- 如果
t1为空且t2为空 → 对称,返回True。 - 如果
t1为空但t2不为空(或反过来) → 不对称,返回False。 - 如果
t1.val != t2.val→ 不对称,返回False。
3.3 递归递推关系
如果 t1.val == t2.val,还要继续检查:
t1的左子树和t2的右子树是否对称。t1的右子树和t2的左子树是否对称。
即:
return isMirror(t1.left, t2.right) and isMirror(t1.right, t2.left)
4. 完整步骤推演(示例 1)
树:
1
/ \
2 2
/ \ / \
3 4 4 3
调用 isSymmetric(root):
- 根节点
1,检查isMirror(节点2, 节点2)。
第一层递归 isMirror(2, 2):
- 值相等(2 == 2)
- 检查
isMirror(2的左=3, 2的右=3)和isMirror(2的右=4, 2的左=4)。
第二层递归 isMirror(3, 3):
- 值相等(3 == 3)
- 检查
isMirror(3的左=None, 3的右=None)→ 都为空,返回True。 - 检查
isMirror(3的右=None, 3的左=None)→ 都为空,返回True。 - 所以
isMirror(3, 3)返回True。
第二层递归 isMirror(4, 4):
- 同理,左右子节点都为空,返回
True。
回到第一层:True and True → True。
所以最终返回 True。
5. 代码实现(Python)
# 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 True
def isMirror(t1, t2):
if not t1 and not t2:
return True
if not t1 or not t2:
return False
return (t1.val == t2.val and
isMirror(t1.left, t2.right) and
isMirror(t1.right, t2.left))
return isMirror(root.left, root.right)
6. 迭代解法思路
除了递归,我们也可以用队列(BFS思想)来迭代判断。
步骤:
- 初始化队列,先把
(root.left, root.right)入队。 - 循环直到队列为空:
- 弹出两个节点
(n1, n2)。 - 如果都为空,继续下一轮。
- 如果一个空一个不空,返回
False。 - 如果值不等,返回
False。 - 入队
(n1.left, n2.right)和(n1.right, n2.left)(注意对称入队顺序)。
- 弹出两个节点
- 循环结束返回
True。
迭代代码:
from collections import deque
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return True
queue = deque([(root.left, root.right)])
while queue:
n1, n2 = queue.popleft()
if not n1 and not n2:
continue
if not n1 or not n2:
return False
if n1.val != n2.val:
return False
queue.append((n1.left, n2.right))
queue.append((n1.right, n2.left))
return True
7. 复杂度分析
- 时间复杂度:
O(n),每个节点访问一次。 - 空间复杂度:
- 递归:
O(h),h 为树高,最坏情况O(n)。 - 迭代:
O(n),队列中最多同时存放 n/2 个节点对。
- 递归:
8. 总结
- 对称二叉树的核心是比较镜像位置的两个节点。
- 递归时注意是 左对右、右对左 的比较。
- 可以用递归(DFS)或迭代(BFS)实现,思路一致。
这样一步步分析,你是否对「对称二叉树」的判断方法清晰了呢?