【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

相关推荐
罗湖老棍子2 小时前
花神游历各国(信息学奥赛一本通- P1550)(洛谷-P4145)
数据结构·算法·线段树·势能数·区间开平方根 区间查询
Mr_Xuhhh2 小时前
LeetCode 热题 100 刷题笔记:数组与排列的经典解法(续)
算法·leetcode·职场和发展
炽烈小老头3 小时前
【每天学习一点算法 2026/03/29】搜索二维矩阵 II
学习·算法·矩阵
靴子学长3 小时前
Qwen3.5 架构手撕源码
算法·架构·大模型
寒月小酒3 小时前
3.28 OJ
算法
AI成长日志3 小时前
【笔面试算法学习专栏】堆与优先队列专题:数组中的第K个最大元素与前K个高频元素
学习·算法·面试
雅俗共赏1003 小时前
医学图像重建中常用的正则化分类
算法
IronMurphy3 小时前
【算法三十二】
算法
Mr_Xuhhh3 小时前
LeetCode 热题 100 刷题笔记:高频面试题详解(215 & 347)
算法·leetcode·排序算法