跟着小码学算法Day16:对称二叉树 - 指南

目录

 一、核心思想:镜像递归 / 成对比较

二、两种通用解法框架

方法一:递归法(DFS - 深度优先搜索)

方法二:迭代法(BFS + 队列)

 三、解题通用步骤(套路化)

四、典型例题


 一、核心思想:镜像递归 / 成对比较

无论是递归还是迭代方法,本质都是在模拟这样一个过程:

比较两个子树 t1t2 是否互为镜像(即对称),需要满足:

  1. 它们的根节点值相等;
  2. t1 的左子树 与 t2 的右子树 是镜像;
  3. t1 的右子树 与 t2 的左子树 是镜像。

这构成了一个分治(Divide and Conquer)结构,非常适合用递归实现。


二、两种通用解法框架

方法一:递归法(DFS - 深度优先搜索)

public boolean isSymmetric(TreeNode root) {
    if (root == null) return true;
    return isMirror(root.left, root.right);
}
private boolean isMirror(TreeNode t1, TreeNode t2) {
    // 1. 都为空 → 对称
    if (t1 == null && t2 == null) return true;
    // 2. 一个为空,另一个不为空 → 不对称
    if (t1 == null || t2 == null) return false;
    // 3. 值不相等 → 不对称
    if (t1.val != t2.val) return false;
    // 4. 递归判断:外侧 + 内侧 是否都对称
    return isMirror(t1.left, t2.right) && isMirror(t1.right, t2.left);
}
特点:
  • 逻辑清晰,代码简洁。
  • 利用了函数调用栈,空间复杂度 O(h),h 为树高。
  • 在深度很大的树中可能栈溢出。

方法二:迭代法(BFS + 队列)

public boolean isSymmetric(TreeNode root) {
    if (root == null) return true;
    Queue queue = new LinkedList<>();
    queue.offer(root.left);
    queue.offer(root.right);
    while (!queue.isEmpty()) {
        TreeNode t1 = queue.poll();
        TreeNode t2 = queue.poll();
        // 同时为空
        if (t1 == null && t2 == null) continue;
        // 一个为空,或值不同
        if (t1 == null || t2 == null || t1.val != t2.val) return false;
        // 成对入队:镜像位置配对
        queue.offer(t1.left);   // 外侧
        queue.offer(t2.right);
        queue.offer(t1.right);  // 内侧
        queue.offer(t2.left);
    }
    return true;
}
特点:
  • 使用显式队列,避免递归栈开销。
  • 更适合宽而深的树(防止栈溢出)。
  • 时间复杂度 O(n),空间复杂度 O(n)

 三、解题通用步骤(套路化)

无论哪种方法,都可以按以下四步走:

步骤内容
1️⃣处理边界情况:如根为空直接返回 true
2️⃣选择比较方式:是单树对称?还是双树比较?→ 构造成两个子树比较的问题
3️⃣设计递归/迭代逻辑
- 递归:定义 isMirror(t1, t2)
- 迭代:使用队列成对入队出队
4️⃣逐层/逐节点判断
- 空值判断
- 值是否相等
- 子树对应关系(镜像 or 相同)

四、典型例题

101. 对称二叉树 - 力扣(LeetCode)

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false

解法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        Queue queue = new LinkedList();
        if(root == null){
            return true;
        }
        queue.offer(root.left);
        queue.offer(root.right);
        while(!queue.isEmpty()){
            TreeNode left = queue.poll();
            TreeNode right = queue.poll();
            if(left==null && right==null){
                continue;
            }
            if(left==null || right==null ||left.val!=right.val){
                return false;
            }
            queue.offer(left.left);
            queue.offer(right.right);
            queue.offer(left.right);
            queue.offer(right.left);
        }
        return true;
    }
}

posted @ 2025-11-09 19:40  gccbuaa  阅读(8)  评论(0)    收藏  举报