【leetcode hot 100】二叉树

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 {
private:
    // 中序遍历辅助函数
    void inorder(TreeNode* node, vector<int>& result) {
        if (node == nullptr) {
            return;
        }
        
        // 1. 先遍历左子树
        inorder(node->left, result);
        
        // 2. 再访问根节点
        result.push_back(node->val);
        
        // 3. 最后遍历右子树
        inorder(node->right, result);
    }

public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        inorder(root, result);
        return result;
    }
};

二叉树中序遍历详解(递归写法,一篇搞懂)

这道题是二叉树的入门基础题,但非常重要,因为它几乎是所有树题的"模板起点"。


一、中序遍历是什么

中序遍历的顺序只有一句话:

左子树 → 根节点 → 右子树

也就是:

复制代码
Left -> Root -> Right

二、代码在做什么

代码是标准递归写法

核心函数:

复制代码
void inorder(TreeNode* node, vector<int>& result)

作用就是:

把以 node 为根的整棵树,按照中序顺序存进 result


三、递归的三步逻辑

复制代码
inorder(node->left, result);
result.push_back(node->val);
inorder(node->right, result);

这三行代码可以理解为:

  1. 先处理左子树

  2. 再处理当前节点

  3. 最后处理右子树

这就是中序遍历的本质。


四、递归终止条件

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

当节点为空时,直接返回

这是所有树递归的"标配"。


五、举个例子理解

比如这棵树:

复制代码
    2
   / \
  1   3

执行顺序是:

复制代码
1 -> 2 -> 3

因为:

  • 先走到最左(1)

  • 再回到根(2)

  • 最后右边(3)


六、为什么中序很重要

在二叉搜索树(BST)中,中序遍历是有序的

例如:

复制代码
BST → 中序遍历 = 升序数组

这就是很多题的核心性质,比如:

  • 验证 BST

  • 转换有序数组

  • 第 k 小元素


七、时间和空间复杂度

时间复杂度:

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

空间复杂度:

O(h),递归栈深度(最坏 O(n),平均 O(log n))


八、非递归写法(进阶)

面试常考:用栈模拟递归

cpp 复制代码
vector<int> inorderTraversal(TreeNode* root) {
    vector<int> res;
    stack<TreeNode*> st;
    TreeNode* cur = root;

    while (cur || !st.empty()) {
        while (cur) {
            st.push(cur);
            cur = cur->left;
        }
        cur = st.top(); st.pop();
        res.push_back(cur->val);
        cur = cur->right;
    }
    return res;
}

九、一句话总结

中序遍历就是:一路向左到底 → 访问 → 转向右边


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:
    int maxDepth(TreeNode* root) {
        if (root == nullptr) {
            return 0;
        }
        int leftDepth = maxDepth(root->left);
        int rightDepth = maxDepth(root->right);
        return max(leftDepth, rightDepth) + 1;
    }
};

二叉树最大深度详解(递归写法,一步看懂)

这道题是二叉树中最经典的递归入门题之一,本质就是一句话:

一棵树的深度 = 左子树深度 和 右子树深度 的最大值 + 1


一、题目本质

给你一棵二叉树,求从根节点到最远叶子节点的最长路径长度。

也就是:

有多少层


二、代码在做什么

cpp 复制代码
int maxDepth(TreeNode* root) {
    if (root == nullptr) {
        return 0;
    }
    int leftDepth = maxDepth(root->left);
    int rightDepth = maxDepth(root->right);
    return max(leftDepth, rightDepth) + 1;
}

这段代码其实就干了三件事:


三、递归三步拆解

1. 终止条件

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

空节点深度是 0


2. 分解子问题

复制代码
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);

分别去计算左子树和右子树的深度


3. 合并结果

复制代码
return max(leftDepth, rightDepth) + 1;

当前节点的深度 = 子树最大深度 + 自己这一层


四、举个例子

复制代码
      3
     / \
    9  20
       / \
      15  7

计算过程:

  • 叶子节点 9、15、7 → 深度 = 1

  • 节点 20 → max(1,1) + 1 = 2

  • 根节点 3 → max(1,2) + 1 = 3

最终答案:

复制代码
3

五、递归本质理解(非常重要)

这题的核心思想是:

把大问题拆成子问题,让子树帮你算

你不用关心整棵树,只需要相信:

  • 左子树会返回它的最大深度

  • 右子树会返回它的最大深度

你只需要做一件事:

取最大 +1


六、时间和空间复杂度

时间复杂度:

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

空间复杂度:

O(h),递归深度(树高)

  • 平衡树:O(log n)

  • 极端链状树:O(n)


七、另一种写法(层序遍历 BFS)

也可以用队列一层一层算:

cpp 复制代码
int maxDepth(TreeNode* root) {
    if (!root) return 0;
    
    queue<TreeNode*> q;
    q.push(root);
    int depth = 0;

    while (!q.empty()) {
        int size = q.size();
        depth++;

        for (int i = 0; i < size; i++) {
            TreeNode* node = q.front(); q.pop();
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
    }
    return depth;
}

每一层循环一次,depth++


八、一句话总结

树的高度问题 = 递归取左右子树最大值 + 1

相关推荐
星星.7222 小时前
C++算法竞赛|二分查找与二分答案:边界模板、浮点二分、STL
数据结构·c++·算法
sel_92 小时前
【OPD论文导读(二)】OPD(On-Policy Distillation)全景调研:十篇论文讲透“在自己生成的内容上学习“这件事
人工智能·python·深度学习·学习·算法·语言模型
金幄科技2 小时前
RAG第四篇:重排序 Rerank——粗召回之后,为什么还需要一次精排
人工智能·算法·ai·ai编程
M78佐菲3 小时前
Linux学习笔记:文件IO
linux·笔记·学习·算法
lhldsg3 小时前
课程排课系统实战指南:从数据库设计到算法调优全流程解析
java·数据库·算法·小程序
BSD_HY3 小时前
薄膜开关矩阵扫描电路设计中的防鬼键措施
人工智能·算法·矩阵·人机交互·薄膜开关·源头工厂·深圳工厂
linux-hzh3 小时前
百日算法修炼 · Day 17
数据结构·算法
XUEYUAN52123 小时前
代理日志分析与监控:代理池健康状态巡检与分级告警体系搭建(运维实战)
运维·网络·网络协议·tcp/ip·算法·架构
sel_94 小时前
【多轮对话论文导读(七)】多轮对话论文阅读笔记:从数据生成、用户模拟到上下文重构与长期记忆
论文阅读·人工智能·笔记·深度学习·算法·语言模型·自然语言处理
远游客07134 小时前
为什么用「年×100+月」做比较
算法·gin