*算法训练(leetcode)第十七天 | 235. 二叉搜索树的最近公共祖先、701. 二叉搜索树中的插入操作、450. 删除二叉搜索树中的节点

刷题记录

  • 235. 二叉搜索树的最近公共祖先
    • 递归
    • 非递归
  • 701. 二叉搜索树中的插入操作
    • 递归
    • 非递归
  • *450. 删除二叉搜索树中的节点

235. 二叉搜索树的最近公共祖先

leetcode题目地址

二叉搜索树(BST),左小右大。在BST中查找两个节点p、q的最近公共祖先时,使用前序遍历,访问到的第一个在两个节点的区间内[p, q]的节点就是公共祖先节点。当前节点值超出区间时借助BST性质(左小右大)向对应的方向缩小范围。

递归

时间复杂度: O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( l o g n ) O(logn) O(logn)

相当于二分查找,访问的是头结点到目标节点路径上的结点,所以时间复杂度最坏是树高logn,空间复杂度是递归的压栈空间,也是树高logn。

// c++
/**
 * 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* inOrder(TreeNode* root, TreeNode* p, TreeNode* q, TreeNode* &result){
        if(!root) return nullptr;
        if(root->val <= q->val && root->val >= p->val) {
            // result = root;
            return root;
        }    
        if(root->val > q->val) return inOrder(root->left, p, q, result);
        if(root->val < p->val) return inOrder(root->right, p, q, result);
        return nullptr;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        // 保证p保存较小值,q保存较大值
        if(p->val > q->val) swap(p, q);
        TreeNode* result=nullptr;
        return inOrder(root, p, q, result);
        // return result;
    }
};

非递归

时间复杂度: O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( 1 ) O(1) O(1)

和递归一样,时间复杂度是树高logn,这里没有使用额外空间,所以空间复杂度是O(1)。

// c++
/**
 * 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* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root) return root;
        if(p->val > q->val) swap(p, q);
        
        while(root){
            if(root->val < p->val){
                root = root->right;
            }else if(root->val > q->val){
                root = root->left;
            }else{
                return root;
            }
        }
        return nullptr;
    }
};

701. 二叉搜索树中的插入操作

leetcode题目地址

中序遍历(什么序遍历都可以,这里使用的是中序),找当前节点大于目标值且左子树为空或者当前节点小于目标值且右子树为空的节点,该结点即为目标值插入的父节点,然后将目标值插入对应位置既可。

时间复杂度: O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( l o g n ) O(logn) O(logn)

递归

// c++
/**
 * 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:

    void inOrder(TreeNode* root, int val){
        if(!root) return;

        if(val < root->val) inOrder(root->left, val); // 左
        
        if(root->val > val && !root->left) {
            root->left = new TreeNode(val);
            return;
        }else if(root->val < val && !root->right){
            root->right = new TreeNode(val);
            return;
        }
        
        if(val > root->val) inOrder(root->right, val);  // 右
    }

    TreeNode* insertIntoBST(TreeNode* root, int val) {
    	// 空树直接返回新节点
        if(!root) return new TreeNode(val);
        inOrder(root, val);
        return root;
    }
};

非递归

// c++
/**
 * 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* insertIntoBST(TreeNode* root, int val) {
        TreeNode* head = root;
        TreeNode* parent = root;

        while(root){
            parent = root;
            if(root->val > val) root = root->left;
            else root = root->right;
        }

        if(!parent) return new TreeNode(val);
        if(parent->val > val) parent->left = new TreeNode(val); 
        else parent->right = new TreeNode(val);

        return head;
    }
};

*450. 删除二叉搜索树中的节点

leetcode题目地址

删除二叉搜索树中节点后需要任保持二叉搜索树的特性(左小右大)。因此在删除结点时分为以下几种情况:

  • 没有找到目标节点,返回当前节点;
  • 目标节点是叶结点(左右孩子为空),直接删除,返回nullptr;
  • 目标节点有一个孩子(左孩子或右孩子非空),则用其孩子节点替换目标节点位置,即删除目标节点,返回孩子节点。
  • 目标节点有两个孩子(左右孩子均非空),则可以用任意一个孩子节点替换目标节点,另一个孩子节点放到对应位置:
    • 使用左孩子替换目标节点,则把右孩子放到左孩子的最右结点(中序遍历中目标节点的前一个结点位置)
    • 使用右孩子替换目标节点,则把左孩子放到右孩子的最左节点(中序遍历中目标节点的后一个结点位置)

删除目标节点,返回对应孩子节点。

时间复杂度: O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( l o g n ) O(logn) O(logn)

// c++
/**
 * 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) return nullptr;
        // 找到目标节点
        if(root->val == key){
            // 叶结点直接删除,返回nullptr
            if(!root->left && !root->right){
                delete root;
                return nullptr;
            }
            // 只有左孩子,返回左孩子
            if(root->left && !root->right) {
                TreeNode* tmp = root;
                root = root->left;
                delete tmp;
                return root; 
            }
            // 只有右孩子,返回右孩子
            if(root->right && !root->left){
                TreeNode* tmp = root;
                root = root->right;
                delete tmp;
                return root; 
            }   
            // 左右孩子都有  用右孩子替代
            if(root->left && root->right){
                TreeNode *tmp = root;
                TreeNode *node = root->right;
                while(node->left){
                    node = node->left;
                }
                node->left = root->left;
                root = root->right;
                delete tmp;
                return root;
            }
        }
        // 继续向左右子树缩小查找域
        if(root->val > key) root->left = deleteNode(root->left, key);
        if(root->val < key) root->right = deleteNode(root->right, key);
        // 没找到 将自己返回
        return root;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣53. 最大子数组和(动态规划)

Problem: 53. 最大子数组和 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.定义dp数组&#xff1a;dp[i]表示以nums[i]为结尾的子序列的最大子序列和&#xff1b; 2.状态初始化&#xff1a;dp[0] nums[0],表示以nums[0]为结尾的子序列的最大子序列和为nums[0]…

linux配置ssh免密登录

1、准备工作 操作系统版本&#xff1a;UnionTech OS Server 20 1050e 内核版本&#xff1a;Linux 4.19.90-2201.4.0.0135.up1.uel20.x86_64 x86_64 使用root用户分别修改每台机器的hosts&#xff0c;添加每台机器所对应的IP和主机名 vi /etc/hosts添加如下内容 172.16.100.1…

Redis-分布式锁(基本原理和不同实现方式对比)

文章目录 1、基本原理2、不同实现方式 1、基本原理 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁&#xff0c;只要大家使用的是同一把锁&#xff0c;那么我们就能锁住线程&#xff0c;不让线程进行&am…

生命在于学习——Python人工智能原理(3.1.1)

Python部分结束了&#xff0c;开始概率论部分 一、概率基本知识 1.1 事件与概率 1.1.1 事件的运算与关系 &#xff08;一&#xff09;基本概念 定义1 随机试验 如果一个试验满足如下条件&#xff1a; 在试验前不能断定其将发生什么结果&#xff0c;但可明确指出或说明试验…

Hugging Face发布重量级版本:Transformer 4.42

Hugging Face 宣布发布Transformer 4.42&#xff0c;该版本为流行的机器学习库带来了许多新功能和增强功能。此版本引入了几个高级模型&#xff0c;支持新工具和检索增强生成 &#xff08;RAG&#xff09;&#xff0c;提供 GGUF 微调&#xff0c;并整合了量化的 KV 缓存&#x…

可以显示余弦函数的自定义控件

序言 终于把坐标系变化怎么玩&#xff0c;搞清楚了。随手写一个余弦函数的自定义控件。只有70行。 代码 package com.example.myapplication;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Pai…

【Emacs Verilog mode保姆级的使用指南】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

# [0701] Task05 策略梯度、Actor-critic 算法

easy-rl PDF版本 笔记整理 P4、P9 joyrl 比对 补充 P9 - P10 相关 代码 整理 最新版PDF下载 地址&#xff1a;https://github.com/datawhalechina/easy-rl/releases 国内地址(推荐国内读者使用)&#xff1a; 链接: https://pan.baidu.com/s/1isqQnpVRWbb3yh83Vs0kbw 提取码: us…

深度学习 --- stanford cs231学习笔记八(训练神经网络之dropout)

6&#xff0c;dropout 6&#xff0c;1 线性分类器中的正则化 在线性分类器中&#xff0c;我们提到过正则化&#xff0c;其目的就是为了防止过度拟合。例如&#xff0c;当我们要用一条curve去拟合一些散点的数据时&#xff0c;常常是不希望训练出来的curve过所有的点&#xff0c…

鸿蒙 DevEcho Studio 查看设备文件

在菜单栏单击View > Tool Windows > Device File Browser&#xff0c;打开Device File Browser。 从下拉列表中选择设备&#xff08;设备需已连接&#xff09;。 选择设备后&#xff0c;显示文件/文件夹列表&#xff0c;可进行以下操作&#xff1a; 右键单击目录…

Qt界面中的子窗口实现鼠标拖动边缘改变大小以及移动(完整demo代码)

目录 效果 拖拽 移动​编辑 实现 DragResizeWgt类.h文件 DragResizeWgt类.cpp文件 使用 testwidget窗口.ui文件 testwidget窗口.h文件 testwidget窗口.cpp文件 参考 效果 想要的效果就是类似于QT IDE中的效果&#xff0c;可以拖动边缘改变大小&#xff0c;用户自身可…

Qt:7.QWidget属性介绍(cursor属性-光标形状、font属性-控件文本样式、tooltip属性-控件提示信息)

目录 一、cursor属性-光标形状&#xff1a; 1.1cursor属性介绍&#xff1a; 1.2获取当前光标形状——cursor()&#xff1a; 1.3 设置光标的形状——setCursor()&#xff1a; 1.4 设置自定义图片为光标&#xff1a; 二、font属性-控件文本样式&#xff1a; 2.1font属性介绍…

一句话介绍什么是AI智能体?

什么是AI智能体&#xff1f; 一句话说就是利用各种AI的功能的api组合&#xff0c;完成你想要的结果。 例如你希望完成一个关于主题为啤酒主题的小红书文案图片&#xff0c;那么它就可以完成 前面几个步骤类似automa的组件&#xff0c;最后生成一个结果。

信息学奥赛初赛天天练-41-CSP-J2021基础题-n个数取最大、树的边数、递归、递推、深度优先搜索应用

PDF文档公众号回复关键字:20240701 2021 CSP-J 选择题 单项选择题&#xff08;共15题&#xff0c;每题2分&#xff0c;共计30分&#xff1a;每题有且仅有一个正确选项&#xff09; 4.以比较作为基本运算&#xff0c;在N个数中找出最大数&#xff0c;最坏情况下所需要的最少比…

汽车内饰塑料件光照老化实验箱

塑料件光照老化实验箱概述 塑料件光照老化实验箱&#xff0c;又称为氙灯老化试验箱&#xff0c;是一种模拟自然光照条件下塑料材料老化情况的实验设备。它通过内置的氙灯或其他光源&#xff0c;产生接近自然光的紫外线辐射&#xff0c;以此来加速塑料及其他材料的光老化过程。…

进程,线程,虚拟内存,交换技术

参考资料&#xff1a; 参考视频1https://www.bilibili.com/video/BV1Hs421M78w/?spm_id_from333.999.0.0&vd_source97411b9a8288d7869f5363f72b0d7613 参考视频2https://www.bilibili.com/video/BV1jE411W7e8/?spm_id_from333.337.search-card.all.click&vd_source…

【创建者模式-建造者模式】

概要 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 建造者模式包含以下角色 抽象建造者类&#xff08;Builder&#xff09;&#xff1a;这个接口规定要实现复杂对象的那些部分的创建&#xff0c;并不涉及具体的部件对象的创建。具体建…

使用explain优化慢查询的业务场景分析

问&#xff1a;你最害怕的事情是什么&#xff1f;答&#xff1a;搓澡问&#xff1a;为什么&#xff1f;答&#xff1a;因为有些人一旦错过&#xff0c;就不在了 Explain 这个词在不同的上下文中有不同的含义。在数据库查询优化的上下文中&#xff0c;“EXPLAIN” 是一个常用的 …

基于PHP的初中数学题库管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的初中数学题库管理系统 一 介绍 此初中数学题库管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;系统角色分为学生&#xff0c;教师和管理员。(附带参考设计文档) 技术栈&#xff1a;phpmysqlphpstudyvscode 二 功能 …

YOLOv10改进教程|C2f-CIB加入注意力机制

一、 导读 论文链接&#xff1a;https://arxiv.org/abs/2311.11587 代码链接&#xff1a;GitHub - CV-ZhangXin/AKConv YOLOv10训练、验证及推理教程 二、 C2f-CIB加入注意力机制 2.1 复制代码 打开ultralytics->nn->modules->block.py文件&#xff0c;复制SE注意力机…