【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

相关推荐
kisshyshy11 小时前
🍦 雪糕、食堂、火车厢:三幅漫画吃透栈、队列与链表
javascript·算法
猿人谷18 小时前
不只是 CPU 阈值:STAR 如何用 GAT + Transformer 做容器级自动扩缩容?
人工智能·算法
复杂网络20 小时前
Stable Diffusion 视觉大模型微调技术深度调研
算法
复杂网络20 小时前
基于 Stable Diffusion 架构的视觉大模型代表性工作与原理深度解析
算法
MrZhao40020 小时前
Agent Loop 如何用 Hook 扩展:权限、日志与工具拦截
算法
MrZhao40020 小时前
Agent 为什么需要 Skills:别把所有知识都塞进 system prompt
算法
JieE2122 天前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2123 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack204 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树4 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色