【leetcode hot 100】 二叉树2

1.

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        // 空节点或叶子节点直接返回
        if (root == nullptr) {
            return nullptr;
        }
        
        // 交换左右子树
        TreeNode* temp = root->left;
        root->left = root->right;
        root->right = temp;
        
        // 递归翻转左右子树
        invertTree(root->left);
        invertTree(root->right);
        
        return root;
    }
};

二叉树翻转(镜像)详解:递归一行思维吃透

这道题本质非常简单,但它是理解递归操作树结构的关键模板题

核心只有一句话:

把每个节点的左右子树交换


一、代码在做什么

cpp 复制代码
TreeNode* invertTree(TreeNode* root) {
    if (root == nullptr) {
        return nullptr;
    }
    
    TreeNode* temp = root->left;
    root->left = root->right;
    root->right = temp;
    
    invertTree(root->left);
    invertTree(root->right);
    
    return root;
}

逻辑非常标准,可以拆成三步。


二、递归三步理解

第一步:终止条件

复制代码
if (root == nullptr) return nullptr;

空节点不用处理


第二步:当前节点做什么

复制代码
swap(root->left, root->right);

把左右子树交换(你用 temp 写法也完全正确)


第三步:递归子树

复制代码
invertTree(root->left);
invertTree(root->right);

让左右子树也各自完成翻转


三、举个例子

原树:

复制代码
    4
   / \
  2   7
 / \ / \
1  3 6  9

翻转后:

复制代码
    4
   / \
  7   2
 / \ / \
9  6 3  1

本质就是每一层都左右对调


四、递归本质(重点)

这题最重要的是理解:

你只负责"当前节点交换",子树交给递归处理

也就是说:

  • 你不用管整棵树怎么翻

  • 你只管这一层

  • 剩下的递归会帮你完成


五、时间和空间复杂度

时间复杂度:

O(n),每个节点访问一次

空间复杂度:

O(h),递归深度


六、非递归写法(层序遍历)

也可以用队列做 BFS:

cpp 复制代码
TreeNode* invertTree(TreeNode* root) {
    if (!root) return root;
    
    queue<TreeNode*> q;
    q.push(root);
    
    while (!q.empty()) {
        TreeNode* node = q.front(); q.pop();
        swap(node->left, node->right);
        
        if (node->left) q.push(node->left);
        if (node->right) q.push(node->right);
    }
    
    return root;
}

七、一句话总结

翻转二叉树 = 每个节点交换左右子树 + 递归处理子树


2.

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if (root == nullptr) return true;
        return isMirror(root->left, root->right);
    }
    
private:
    bool isMirror(TreeNode* left, TreeNode* right) {
        // 两个都为空,对称
        if (left == nullptr && right == nullptr) return true;
        // 一个为空一个不为空,不对称
        if (left == nullptr || right == nullptr) return false;
        // 值不相等,不对称
        if (left->val != right->val) return false;
        
        // 递归检查:左的左 vs 右的右,左的右 vs 右的左
        return isMirror(left->left, right->right) && 
               isMirror(left->right, right->left);
    }
};

对称二叉树详解:镜像递归一眼看透

这道题是二叉树递归的经典题,核心思想其实非常统一:

判断两棵子树是否"镜像对称"


一、题目本质

一棵树是对称的,本质就是:

左子树 和 右子树 互为镜像

也就是:

  • 左的左 = 右的右

  • 左的右 = 右的左


二、代码在做什么

cpp 复制代码
bool isSymmetric(TreeNode* root) {
    if (root == nullptr) return true;
    return isMirror(root->left, root->right);
}

从根节点开始,比较左右子树


核心函数:

复制代码
bool isMirror(TreeNode* left, TreeNode* right)

判断两棵树是否互为镜像


三、递归核心逻辑

可以理解为四步:


第一步:都为空 → 对称

第二步:一个空一个不空 → 不对称

第三步:值不同 → 不对称

第四步:递归判断"镜像结构"

左.left 对比 右.right

左.right 对比 右.left


四、举个例子

对称树:

复制代码
    1
   / \
  2   2
 / \ / \
3  4 4  3

判断过程:

  • 2 和 2 ✔

  • 3 和 3 ✔

  • 4 和 4 ✔

最终返回 true


不对称:

复制代码
    1
   / \
  2   2
   \   \
   3    3

左右结构不匹配 → false


五、递归本质(重点)

这题的核心思想是:

把"整棵树对称"转化为"两个子树是否镜像"

你不需要关心整棵树,只需要定义:

函数 isMirror(left, right)

剩下的递归会帮你完成。


六、时间和空间复杂度

时间复杂度:

O(n),每个节点访问一次

空间复杂度:

O(h),递归深度


七、非递归写法(队列)

也可以用队列做:


八、一句话总结

对称二叉树 = 判断左右子树是否镜像(交叉递归)

相关推荐
白羊by24 分钟前
YOLOv1~v11 全版本核心演进总览
深度学习·算法·yolo
墨尘笔尖2 小时前
最大最小值降采样算法的优化
c++·算法
skylijf3 小时前
2026 高项第 6 章 预测考点 + 练习题(共 12 题,做完稳拿分)
笔记·程序人生·其他·职场和发展·软件工程·团队开发·产品经理
white-persist4 小时前
【vulhub shiro 漏洞复现】vulhub shiro CVE-2016-4437 Shiro反序列化漏洞复现详细分析解释
运维·服务器·网络·python·算法·安全·web安全
FL16238631295 小时前
基于C#winform部署软前景分割DAViD算法的onnx模型实现前景分割
开发语言·算法·c#
baizhigangqw5 小时前
启发式算法WebApp实验室:从搜索策略到群体智能的能力进阶
算法·启发式算法·web app
C雨后彩虹5 小时前
最多等和不相交连续子序列
java·数据结构·算法·华为·面试
一江寒逸6 小时前
零基础从入门到精通 AI Agent 开发(全栈保姆级教程)附加篇:AI Agent 面试八股文全集
人工智能·面试·职场和发展
久菜盒子工作室6 小时前
面试经验|产品经理|自我介绍
面试·职场和发展·产品经理
cpp_25016 小时前
P2347 [NOIP 1996 提高组] 砝码称重
数据结构·c++·算法·题解·洛谷·noip·背包dp