代码随想录算法训练营第二十二天 | 235. 二叉搜索树的最近公共祖先, 701.二叉搜索树中的插入操作, 450.删除二叉搜索树中的节点

news2025/1/11 22:51:39

在这里插入图片描述
在这里插入图片描述
这道题和寻找二叉树的最近祖先可以用同一套解法,也就是说,考虑当你站在一个节点上的时候,应该干啥:看当前节点是不是指定的孩子p,q,然后检查左子树有无指定节点,检查右子树有无指定节点,那天然就是一个后序遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution {
public:
    TreeNode* res = NULL;
    bool traceback(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == NULL) {
            return false;
        }

        bool leftRes = traceback(root->left, p, q);
        bool rightRes = traceback(root->right, p, q);
        bool rootRes = (root == p || root == q) ? true : false;

        if (rootRes == true) {
            if (leftRes == true && rightRes == true) {
                if (res == NULL) {
                    res = root;
                }
                return true;
            } else if ((leftRes == true) || (rightRes == true)) {
                if (res == NULL) {
                    res = root;
                }
                return true;
            } else{
                return true;
            }

        } else {
             if (leftRes == true && rightRes == true) {
                if (res == NULL) {
                    res = root;
                }
                return true;
            } else if ((leftRes == true) || (rightRes == true)) {
                return true;
            } else{
                return false;
            }
        }
        return false;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        traceback(root, p, q);
        return res;
    }
};

这道题自然是有除了二叉树通解以外的解法的,实际上,BST的大小关系是可以指示检索方向的,根据BST性质去检索各个节点,当发现某个节点的值恰好处于p,q之间时,这个节点就是最近公共祖先

在这里插入图片描述
在这里插入图片描述
二叉搜索树顺序搜索,遇到第一个可以插入的位置直接插就行

/**
 1. Definition for a binary tree node.
 2. struct TreeNode {
 3.     int val;
 4.     TreeNode *left;
 5.     TreeNode *right;
 6.     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 7.     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 8.     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 9. };
 */
class Solution {
public:
    void traceback(TreeNode* root, const int &val){
        if(root == NULL){
           return;
        }
        
        if(root->val > val){
            if(root->left != NULL){
                traceback(root->left,val);
            }else{
                TreeNode * node = new TreeNode(val);
                root->left = node;
                return;
            }           
        }else if(root->val < val){
             if(root->right != NULL){
                traceback(root->right,val);
            }else{
                TreeNode * node = new TreeNode(val);
                root->right = node;
                return;
            }          
        }       
    }
    TreeNode* insertIntoBST(TreeNode* root, int val) {
         if(!root){
           TreeNode * node = new TreeNode(val);
           root = node;
         }
         traceback(root,val);
         
         return root;
    }
};

在这里插入图片描述
在这里插入图片描述
这道题,实际上是一个先序遍历的遍历结构,但是先序遍历找到对应的节点以后有四种情况需要处理:

  1. 找到的节点是叶子节点,直接删除,父节点指NULL
  2. 找到的节点是只有右子树,无左子树,这时候直接跳过这个节点,把存在的子树接到父节点下
  3. 同理。找到的节点是只有左子树,无右子树,这时候直接跳过这个节点,把存在的子树接到父节点下
  4. 找到的节点左右子树都不为空,做一个子树的右旋操作,左子树接到右子树的最左节点上,这个时候被删除节点的左子树被移动后,原位置为空,问题就变成了只有右子树无左子树的问题

我们在返回时需要确定待删除节点是在父节点的左子树还是右子树,这个就太麻烦了,直接递归式构造遍历即可

/**
 * 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:
    TreeNode* deleteNode(TreeNode* root, int key) {
          if(root == NULL){
              return NULL;
          }
          
          if(root->val == key){
              if(root->left == NULL && root->right == NULL){
                  return NULL;
              }else if(root->left == NULL && root->right != NULL){
                  return root->right;
              }else if(root->left != NULL && root->right == NULL){
                  return root->left;
              }else{
                  TreeNode * node = root->right;
                  while(node != NULL){
                      if(node->left == NULL){
                          node->left = root->left;
                          break;
                      }
                      node = node->left;
                  }
                  return root->right;
                  
              }
          }
          if(root->val > key) {root->left = deleteNode(root->left,key);}
          if(root->val < key) {root->right = deleteNode(root->right,key);}
        return root;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1524327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HashMap底层是如何实现的?

1、典型回答 不同的JDK 版本&#xff0c;HashMap 的底层实现是不一样的&#xff0c;总体来说&#xff1a;在JDK 1.8 之前(不包含JDK 1.8)&#xff0c;HashMap 使用的是数组 链表实现的&#xff0c;而JDK 1.8之后(包含JDK 1.8)使用的是数组 链表或红黑树实现的 HashMap 在JD…

鸿蒙Next 支持数据双向绑定的组件:Checkbox--Search--TextInput

Checkbox $$语法&#xff0c;$$绑定的变量发生变化时&#xff0c;会触发UI的刷新 Entry Component struct MvvmCase { State isMarry:boolean falseStatesearchText:string build() {Grid(){GridItem(){Column(){Text("checkbox 的双向绑定")Checkbox().select($$…

python学习笔记------函数进阶

函数多返回值 函数返回多个返回值格式 def 函数名(): return 1,2,......,n x,x1,......xn函数名&#xff08;&#xff09; 按顺序接受 函数的多种传参方式 位置参数&#xff1a;调用函数时根据函数定义的参数位置来传递参数 传递的参数和定义的参数的顺序及个数必须一致…

简介:项目管理九大知识五大过程

前言 项目管理&#xff08;Project Management,PM/Management by Projects,MBP&#xff09; 在有限的资源约束下&#xff0c;运用系统的观点、方法和理论&#xff0c;对项目涉及的全部工作进行有效地管理。即从项目的投资决策开始到项目结束的全过程进行计划、组织、指挥、协调…

WPF监控平台(科技大屏)[一]

跟着B站的视频敲了一个略微复杂的WPF界面,链接如下.在这里我详细的写一份博客进行设计总结. 系统介绍和配置及主窗口设计_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Wy421Y7QD?p1&vd_source4796b18a2e4c1ec8a310391a5644b6da 成果展示 实现过程 总体来说,我的…

打破数据孤岛,TDengine 与 Tapdata 实现兼容性互认证

当前&#xff0c;传统行业正面临着数字化升级的紧迫需求&#xff0c;但海量时序数据的处理以及数据孤岛问题却日益突出。越来越多的传统企业选择引入时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;升级数据架构&#xff0c;同时&#xff0c;为了克服…

redis题库详解

1 什么是Redis Redis(Remote Dictionary Server) 是一个使用 C 语言编写的&#xff0c;开源的&#xff08;BSD许可&#xff09;高性能非关系型&#xff08;NoSQL&#xff09;的键值对数据库。 Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串&#xff0c;…

《LeetCode热题100》笔记题解思路技巧优化_Part_4

《LeetCode热题100》笔记&题解&思路&技巧&优化_Part_4 &#x1f60d;&#x1f60d;&#x1f60d; 相知&#x1f64c;&#x1f64c;&#x1f64c; 相识&#x1f622;&#x1f622;&#x1f622; 开始刷题二叉树&#x1f7e2;1. 二叉树的中序遍历&#x1f7e2;2.…

如何在idea中配置tomcat服务器,然后部署一个项目

文章目录 前言第一步 先新建一个空项目第二步 添加框架支持第三步 添加配置及如何部署最后一步 运行及检查有没有问题总结 前言 本章学习的是在idea中配置tomcat服务器&#xff0c;然后部署一个项目 如果没有下载Tomcat服务器的可以在上一个博客观看下载及手动部署&#xff0c;…

纯 CSS 实现文字换行环绕效果

实现效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title><…

SwiftUI的Alert使用方式

SwiftUI的Alert使用方式 记录一下SwiftUI的Alert使用方式&#xff0c;比较简单直接上代码 import SwiftUIstruct AlertBootCamp: View {State var showAlert falsevar body: some View {Button {showAlert.toggle()} label: {Text("alert show")}/// 单按钮 // …

Acwing-基础算法课笔记之动态规划(计数类DP)

Acwing-基础算法课笔记之动态规划&#xff08;计数类DP&#xff09; 一、整数划分1、定义2、完全背包的做法代码示例&#xff08;1&#xff09;过程模拟&#xff08;2&#xff09;代码示例 3、计数类DP的做法&#xff08;1&#xff09;过程模拟&#xff08;2&#xff09;闫氏DP…

文件包含漏洞(input、filter、zip)

一、PHP://INPUT php://input可以访问请求的原始数据的只读流&#xff0c;将post请求的数据当作php代码执行。当传入的参数作为文件名打开时&#xff0c;可以将参数设为php://input,同时post想设置的文件内容&#xff0c;php执行时会将post内容当作文件内容。从而导致任意代码…

Gogs 创建新的仓库并提交代码

Gogs 创建新的仓库并提交代码 1. 登录2. 仓库 -> 我的仓库3. 创建新的仓库4. 仓库5. Copy6. 公开代码​7. 提交成功 Gogs - gitReferences Gogs 是一款极易搭建的自助 Git 服务。 1. 登录 2. 仓库 -> 我的仓库 3. 创建新的仓库 4. 仓库 5. Copy 6. 公开代码 strongfo…

【MySQL】表的约束(2)

【MySQL】表的约束&#xff08;2&#xff09; 目录 【MySQL】表的约束&#xff08;2&#xff09;自增长唯一键外键综合案例-阅读 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2024.3.13 前言&#xff1a;本篇博客主要是介绍表的约束下部分内容(自增长&#xff0c;唯一键&a…

计算机考研|怎么备考「科软」?

学好408和考研数学就可以了 大家对于科软已经回到了理性的区间&#xff0c;很难再出现刚开始的300分上科软的现象&#xff0c;也不会再出现388分炸穿地心的现象。 如果大家想报考科软&#xff0c;我觉得一定要认真对待复习&#xff0c;不要抱有抄底的心态去复习。 众所周知&am…

QtCreate cmake 和qmake 使用调用动态库流程

链接&#xff1a; QtCreate cmake 和qmake 使用调用静态库流程-CSDN博客 重点&#xff1a; 1.流程和静态库一样。 2.只是在include下放置所需的dll。 3.cmakelist.txt中的文件路径并未变化。

Selenium抓取youtube视频推荐

Youtube作为一个全球最大的视频资源平台&#xff0c;对于视频资源有很好的规整处理。所以当我们想要抓取一些视频资源时&#xff0c;它本身提供的API能力不符合时&#xff0c;我们需要使用Selenium去抓取视频。 以下是根据一条视频链接去抓取推荐列表的功能&#xff1a; asyn…

不锈钢多功能电工剥线钳分线绕线剪线剥线钳剥线压线扒皮钳子

品牌&#xff1a;银隆 型号&#xff1a;089B绿色 材质&#xff1a;镍铬钢&#xff08;不锈钢&#xff09; 颜色分类&#xff1a;089B灰色,089B红色,089B绿色,089B黑色,089B橙色 功能齐集一身&#xff0c;一钳多用&#xff0c;多功能剥线钳。剥线&#xff0c;剪线&#xff…

前端三件套 | 综合练习:模拟抽奖活动,实现一个简单的随机抽取并显示三名获胜者

随机运行结果如下&#xff1a; 参考代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><tit…