当前位置: 首页 > news >正文

day20

235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {int x = root->val;if(p->val < x && x > q->val){ // 递归左子树return lowestCommonAncestor(root->left, p, q);}if(p->val > x && q->val > x){return lowestCommonAncestor(root->right, p, q);}return root;}
};

701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {if(root == nullptr) return new TreeNode(val);if(root->val > val){root->left = insertIntoBST(root->left, val);}else{root->right = insertIntoBST(root->right, val);}return root;} 
};

先记住 BST 的规则

  • 左子树所有值 < 根节点值

  • 右子树所有值 > 根节点值
    (这题保证没有重复;若允许重复,我们统一规定“相等走右边”也行。)


这个函数的“承诺”(很关键)

insertIntoBST(root, val) 承诺

val 正确插到以 root 为根的这棵子树里,并返回“插入后这棵子树的根指针”。

有了这个承诺,下面每行就特别好理解了。


每一行在干嘛

if (!root) return new TreeNode(val);

  • 如果当前这棵子树根本就不存在(指针是 nullptr),说明我们走到了一个空位——正是新节点该放的位置。

  • 于是创建新节点并把它的指针返回上去。
    这就是递归的终止条件(base case)。

root->left = insertIntoBST(root->left, val);

  • 如果 val 比当前 root->val 小,它应该在左子树里。

  • 我们把“在左子树里插入”的任务递给左孩子insertIntoBST(root->left, val)

  • 这一步会返回“插完之后的左子树根指针”。我们再把它接回root->left 上。
    这样做的意义:万一左子树本来是空(nullptr),递归会创建一个新节点并返回它的指针,我们接回去,就把新节点挂成了 root 的左孩子。

root->right = insertIntoBST(root->right, val);

  • 同理,若 val 大(或相等时统一走右边),就把任务丢给右子树,并把“插完后的右子树根指针”接回 root->right

return root;

  • 别忘了我们函数的承诺:返回“插入后这棵子树的根”。

  • 对于当前这一层来说,根就是 root 本人(我们可能改动的是它的左/右孩子指针),所以把 root 原样返回即可。

  • 最顶层返回的就是整棵树的根;这点对“原本空树”的情况尤其重要:如果 root 一开始是 nullptr,第一行会新建节点并返回,新根就被正确传回给调用者了。


走一遍例子(最能帮你建立直觉)

假设当前树是:

    7/ \3   9

插入 5

  1. 调用 insert(7, 5):5 < 7,去左子树
    root->left = insert(3, 5)

  2. 调用 insert(3, 5):5 > 3,去右子树
    root->right = insert(nullptr, 5) (因为 3 的右孩子本来是空)

  3. 调用 insert(nullptr, 5):命中空位,return new Node(5)

  4. 回到第二层:把返回的指针接回 3->right,然后 return 3

  5. 回到第一层:把返回的指针接回 7->left(其实还是原来的 3,只是它多了个右孩子 5),然后 return 7

结果树:

    7/ \3   9\5

你看到“接回去”的意义了吧:谁递归下去,谁负责把子树接回来


复杂度 & 栈深

  • 时间:O(h)h 是树高;平衡时约 log n,退化成链时是 n)。

  • 额外空间:递归调用栈 O(h)(迭代写法可做到 O(1))。


常见疑问速答

  • 为什么要写 root->left = … / root->right = …
    因为递归可能在空位创建一个新节点并把它的指针返回来,你必须把这个指针挂回到父节点对应的孩子指针上,这样树才更新到最新形态。

  • 为什么最后 return root 就行?
    当前这一层的“子树根”就是 root 本人;我们只可能改了它的孩子指针,但根没变,所以返回它就满足“承诺”。

  • 如果原树是空的呢?
    顶层 rootnullptr,第一行会 new 一个节点并直接返回;调用者拿到的就是新根。

450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {if(!root) return nullptr; // if(key < root->val){ // 递归左子树root->left = deleteNode(root->left, key);} else if(key > root->val){root->right = deleteNode(root->right, key);} else{ // 找到要删除的节点if(root->left == nullptr){return root->right;}if(root->right == nullptr) return root->left;if(root->left && root->right){TreeNode* node = root->left;while(node->right){node = node->right;}root->val = node->val;root->left = deleteNode(root->left,node->val);}}return root;}
};

http://www.dtcms.com/a/329514.html

相关文章:

  • Qwen-Image(阿里通义千问)技术浅析(二)
  • GDB命令笔记
  • Windows也能用!Claude Code硬核指南
  • 2021 年全国硕士研究生招生考试真题笔记
  • 基于DDPG的车辆纵向速度控制优化:兼顾速度与乘坐舒适性
  • React UI 框架
  • Vue3 使用 echarts 甘特图(GanttChart)
  • 【(一)页面布局】
  • 海康视觉平台VM创建项目
  • JAVA实战小项目——输入验证码
  • rtmp 推流
  • 浅层神经网络
  • Dimensional Analysis量纲分析入门
  • 猫粮哪个牌子质量好性价比高?2025适合幼猫的猫粮推荐
  • LangGraph 指南篇-基础控制
  • GaussDB 动态内存过高处理办法
  • 从表单校验到API网关:全链路输入安全防护指南
  • SeaTunnel MCP Server 入选《中国信通院开源商业产品及企业典型案例集(2025)》
  • 开源日志log4cplus—如何将 string类型转为tstring类型,又如何将char*类型转换为tstring类型?
  • 机器学习入门:核心概念详解与Python示例代码
  • 飞算JavaAI的“盾牌”计划:手撕Spring Security + JWT认证链
  • 【debian系统】cuda13和cudnn9.12详细安装步骤
  • 常用机器学习公开数据集大全
  • Spring、Spring MVC、Spring Boot与Spring Cloud的扩展点全面梳理
  • model层实现:
  • 设计模式笔记_行为型_策略模式
  • 【前端Vue】使用ElementUI实现表单中可选择可编辑的下拉框
  • 用 Qt C++ 从零打通“前端界面 → 后端接口”的数据交互
  • 为什么 sim(3) 中的尺度 s 与旋转 R 相乘,而不是平移 t?
  • Go语言实战案例:使用Gin处理路由参数和查询参数