LeetCode 第 101 题「对称二叉树」
字数 1632 2025-10-25 20:04:12
好的,我们这次来学习 LeetCode 第 101 题「对称二叉树」。
1. 题目描述
原题链接:https://leetcode.com/problems/symmetric-tree/
题目:
给定一个二叉树的根节点 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 递归思路
我们可以设计一个递归函数 isMirror(left, right),判断两棵树 left 和 right 是否互为镜像。
镜像条件:
left和right的根节点值相等。left的左子树与right的右子树互为镜像。left的右子树与right的左子树互为镜像。
特殊情况:
- 如果
left和right都为空,则对称(true)。 - 如果只有一个为空,则不对称(false)。
初始调用时,传入整棵树的左子树和右子树:isMirror(root.left, root.right)。
3.2 迭代思路
也可以用队列(或栈)来模拟递归过程:
- 初始将
(root.left, root.right)入队。 - 每次出队两个节点
l和r:- 如果都为空,继续。
- 如果只有一个为空,返回 false。
- 如果值不相等,返回 false。
- 否则,按对称顺序入队:
(l.left, r.right)和(l.right, r.left)。
- 队列空时说明检查完毕,返回 true。
4. 递归解法详细步骤
步骤 1:定义递归函数
boolean check(TreeNode l, TreeNode r)
步骤 2:处理基本情况
- 如果
l == null && r == null→ 返回 true - 如果
l == null || r == null→ 返回 false - 如果
l.val != r.val→ 返回 false
步骤 3:递归检查
- 返回
check(l.left, r.right) && check(l.right, r.left)
步骤 4:主函数
- 如果根为空,返回 true(空树对称)
- 否则返回
check(root.left, root.right)
代码实现(Java):
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return check(root.left, root.right);
}
private boolean check(TreeNode l, TreeNode r) {
if (l == null && r == null) return true;
if (l == null || r == null) return false;
if (l.val != r.val) return false;
return check(l.left, r.right) && check(l.right, r.left);
}
}
5. 迭代解法详细步骤
用队列(BFS 思路)实现:
步骤 1:初始化队列,加入 (root.left, root.right)
步骤 2:循环直到队列为空
- 弹出两个节点
l和r - 如果都为空,continue
- 如果只有一个为空,返回 false
- 如果值不等,返回 false
- 入队
(l.left, r.right)和(l.right, r.left)
步骤 3:循环结束返回 true
代码实现(Java):
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root.left);
queue.offer(root.right);
while (!queue.isEmpty()) {
TreeNode l = queue.poll();
TreeNode r = queue.poll();
if (l == null && r == null) continue;
if (l == null || r == null) return false;
if (l.val != r.val) return false;
queue.offer(l.left);
queue.offer(r.right);
queue.offer(l.right);
queue.offer(r.left);
}
return true;
}
}
6. 复杂度分析
- 时间复杂度:O(n),每个节点访问一次。
- 空间复杂度:
- 递归:O(h),h 是树高,最坏 O(n)(退化为链表)。
- 迭代:O(n),队列中最多同时存放 n/2 个节点对。
7. 总结
- 对称二叉树的关键是比较对称位置的节点,而不是同一层的节点直接比较。
- 递归思路直观,迭代思路用队列模拟递归过程。
- 注意处理空节点的特殊情况。
需要我再用一个具体的例子,一步步演示递归或迭代的过程吗?这样可以帮助你更直观地理解每一步是如何进行的。