【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

相关推荐
发发就是发1 天前
USB系统架构概述:从一次诡异的枚举失败说起
驱动开发·单片机·嵌入式硬件·算法·fpga开发
少许极端1 天前
算法奇妙屋(四十七)-ST表
算法·st表·rmq
kishu_iOS&AI1 天前
Pytorch —— 自动微分模块
人工智能·pytorch·python·深度学习·算法·线性回归
北风toto1 天前
深入解析JWT Token生成原理与安全加密技术详解
算法·安全·哈希算法
DeepModel1 天前
通俗易懂讲透 EM 算法(期望最大化)
人工智能·python·算法·机器学习
Pentane.1 天前
【力扣hot100】【Leetcode 15】三数之和|暴力枚举 双指针 算法笔记及打卡(14/100)
数据结构·笔记·算法·leetcode
不知名的老吴1 天前
高阶函数的应用与函数对象概念
算法
Mr_pyx1 天前
【LeetCode Hot 100】 - 缺失的第一个正数完全题解
数据结构·算法
wydxry1 天前
深入解析自适应光学中的哈特曼波前传感技术:原理、算法与智能化前沿
大数据·人工智能·算法
xieliyu.1 天前
Java顺序表实现扑克牌Fisher-Yates 洗牌算法
java·数据结构·算法·javase