【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:
    int count = 0;  // 当前访问的节点计数
    int result = 0; // 存储第 k 小的值
    
    void inorder(TreeNode* root, int k) {
        if (!root) return;
        
        // 左子树
        inorder(root->left, k);
        
        // 访问当前节点
        count++;
        if (count == k) {
            result = root->val;
            return;
        }
        
        // 右子树
        inorder(root->right, k);
    }
    
public:
    int kthSmallest(TreeNode* root, int k) {
        inorder(root, k);
        return result;
    }
};

二叉搜索树第 k 小元素:中序遍历一招解决

这道题是 BST(搜索树)里非常经典的一题,本质就一句话:

利用 BST 的"中序遍历有序"性质


一、题目本质

在 BST 中找第 k 小的数


二、核心性质(关键)

BST 的中序遍历 = 升序序列

复制代码
Left → Root → Right

例如:

复制代码
    5
   / \
  3   7
 / \
2   4

中序遍历:

复制代码
2 → 3 → 4 → 5 → 7

第 k 小 = 第 k 个访问到的节点


三、代码在做什么

全局变量

复制代码
int count = 0;
int result = 0;

count:记录访问到第几个节点

result:记录答案


中序遍历

复制代码
void inorder(TreeNode* root, int k)

四、递归核心逻辑

复制代码
inorder(root->left, k);

先访问更小的节点


复制代码
count++;
if (count == k) {
    result = root->val;
    return;
}

找到第 k 个,直接记录


复制代码
inorder(root->right, k);

再访问更大的节点


五、执行过程(必须理解)

假设:

复制代码
k = 3

中序序列:

复制代码
2 → 3 → 4 → 5 → 7

过程:

  • 访问 2 → count=1

  • 访问 3 → count=2

  • 访问 4 → count=3 ✔

返回 4


七、时间和空间复杂度

时间复杂度:

O(k) ~ O(n)

最好情况只走到第 k 个

空间复杂度:

O(h)


八、进阶解法

如果是"动态 BST"(频繁插入删除):

可以用:

  • 节点记录子树大小(Order Statistic Tree)

这样可以:

O(log n) 找第 k 小


九、这一题的本质

把"第 k 小"转化为"中序第 k 个访问节点"


十、一句话总结

👉 BST 第 k 小 = 中序遍历第 k 次访问

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 {
private:
    int max_sum;
    int dfs(TreeNode* node)
    {
        if(!node)
        {
            return 0;
        }
        int left=max(0,dfs(node->left));
        int right=max(0,dfs(node->right));
        int current=node->val+left+right;
        max_sum=max(max_sum,current);
        return node->val+max(left,right);
    }
    
public:
    int maxPathSum(TreeNode* root) {
        max_sum = INT_MIN;
        dfs(root);
        return max_sum;
    }
};

二叉树最大路径和详解:最难树题之一,彻底讲透

这道题是树里含金量非常高的一题,很多人会卡在两个点:

  • 为什么要 max(0, ...)

  • 为什么返回值和更新答案不一样

你这份代码已经是最优标准解法,我们把它彻底拆开。


一、题目本质

找一条路径,使得路径和最大

注意:

  • 路径可以从任意节点开始

  • 路径可以在任意节点结束

  • 不一定经过根节点


二、核心思想(最关键一句话)

每个节点都可以作为"路径的拐点"

路径形态是:

复制代码
左子树 → 当前节点 → 右子树

三、代码在做什么

复制代码
int dfs(TreeNode* node)

返回:从当前节点向下走的最大路径和(单边)

同时:

在过程中更新全局最大值 max_sum


四、递归核心拆解(重点)

1. 终止条件

复制代码
if (!node) return 0;

2. 计算左右子树

复制代码
int left = max(0, dfs(node->left));
int right = max(0, dfs(node->right));

关键点来了:

  • 如果子树是负数 → 不要(当作 0)

  • 因为负数只会拖累路径


3. 更新最大路径

复制代码
int current = node->val + left + right;
max_sum = max(max_sum, current);

这是"完整路径":

复制代码
左 + 当前 + 右

4. 返回值(非常关键)

复制代码
return node->val + max(left, right);

只能选一边!

因为:

往上走的路径不能分叉


五、举个例子(必须理解)

复制代码
      -10
      /  \
     9   20
        /  \
       15   7

分析:

  • 节点 20:15 + 20 + 7 = 42 ✔

  • 这是最大路径

注意:路径没有经过根节点!


六、两个"最大值"的区别

1. max_sum

全局最大路径(可以左右都选)


2. dfs 返回值

只能选一边,用于向上传递


这是这题最核心的区别!


七、时间和空间复杂度

时间复杂度:

O(n)

空间复杂度:

O(h)


八、这题的本质

后序遍历 + 分两种路径计算

  • 一种:更新答案(左右都要)

  • 一种:返回父节点(只能选一边)

相关推荐
ZPC82102 小时前
MoveIt Servo 控制真实机械臂
人工智能·pytorch·算法·性能优化·机器人
88号技师2 小时前
2026年3月新锐一区SCI-随机社会学习优化算法Stochastic social learning-附Matlab免费代码
学习·算法·数学建模·matlab·优化算法
小此方2 小时前
Re:从零开始的 C++ STL篇(十)map/set使用精讲:常见问题与典型用法(上)
开发语言·数据结构·c++·算法·stl
88号技师2 小时前
2025年11月一区SCI-壁虎优化算法Gekko Japonicus Algorithm-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
浅念-2 小时前
LeetCode 双指针题型 C++ 解题整理
开发语言·数据结构·c++·笔记·算法·leetcode·职场和发展
Mr_Xuhhh2 小时前
LeetCode hot 100(C++版本)
c++·leetcode·哈希算法
故事和你912 小时前
洛谷-入门6-函数与结构体
开发语言·数据结构·c++·算法·动态规划
青瓷程序设计2 小时前
【基于 YOLO的咖啡豆果实成熟度检测系统】+ Python+算法模型+目标检测+2026原创
python·算法·yolo
程序员Shawn2 小时前
【机器学习 | 第七篇】- 聚类算法
算法·机器学习·聚类