LeetCode 450.删除二叉搜索树中的节点和669.修建二叉搜索树思路对比 及heap-use-after-free问题解决

news2025/5/24 11:16:58

题目描述 

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

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

示例 1:

输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。


669.修建二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1:

输入:root = [1,0,2], low = 1, high = 2
输出:[1,null,2]

示例 2:

输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3
输出:[3,2,null,1]

思路对比

450题目在处理的时候需要分为五种情况,因为它需要改变子树的结构并且改变的方式不唯一:

第一种是二叉搜索树中不存在要寻找的节点

第二种是需要删除叶子节点

第三种是要删除的节点只有左子叶,没有右子叶

第四种是只有右子叶,没有左子叶

第五种是最难处理的,左右子叶都有,加入上图中要删除的节点是7,对于这一种情况处理的方式是选择右子叶9作为新的代替7的节点,然后将5 4 6这一左子树移动到8底下,也就是9这个子树下最小的数字。从代码上编写,就是一直向左搜寻,搜寻到叶子节点为止,就找到8了。

而669题目中说不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。这道题出现第五种情况时与上一题不同的地方在于,如果当前节点小于low,那么它的整个左子树都需要被裁剪,如果大于high,整个右子树也需要被裁减,所以它不需要像上一题的第五种情况一样,对整个树的结构进行大的改变。当前节点小于low,就直接将上一节点指向右子树(右子树的值也需要裁剪)

代码实现

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

/**
 * 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->left;
            else if(root->right != NULL && root->left == NULL) return root->right;
            else{
                TreeNode* cur = root->right;
                while(cur->left){
                    cur = cur->left;
                }
                cur->left = root->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;
    }
};

669. 修剪二叉搜索树

/**
 * 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* trimBST(TreeNode* root, int low, int high) {
        if(root == NULL) return NULL;
        if(root->val < low){
            TreeNode* right = trimBST(root->right,low,high);
            return right;
        }
        if(root->val >high){
            TreeNode* left = trimBST(root->left,low,high);
            return left;
        }
        root->left = trimBST(root->left,low,high);
        root->right = trimBST(root->right,low,high);
        return root;
    }
};

heap-use-after-free问题

开始解决669问题时完全套用450的思路,代码如下,出现了报错 

/**
 * 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* trimBST(TreeNode* root, int low, int high) {
        if(root == NULL) return NULL;
        if(root->val < low || root->val > high){
            if(root->left == NULL && root->right == NULL) return NULL;
            else if(root->left != NULL && root->right == NULL) return root->left;
            else if(root->right != NULL && root->left == NULL) return root->right;
            else{
                TreeNode* cur = root->right;
                while(cur->left){
                    cur = cur->left;
                }
                cur->left = root->left;
                return root->right;
            }
        }
        root->left = trimBST(root->left,low,high);
        root->right = trimBST(root->right,low,high);
        return root;
    }
};

发现问题出现在尾节点root->left本来有值,但是现在将它的节点全都转移到其他地方了,要将这个尾节点指向NULL就行,修改代码如下:

else{
                TreeNode* cur = root->right;
                while(cur->left){
                    cur = cur->left;
                }
                cur->left = root->left;
                root->left = NULL;
                return root->right;
            }
        }

 

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

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

相关文章

代码控制写入excel文件

1、引言 在工作和学习中&#xff0c;我们经常使用到excel表格&#xff0c;有时候表格中的数据很多&#xff0c;此时我们就希望能够通过程序去控制某些表格数据的生成和修改&#xff0c;从而达到简化操作&#xff0c;缩减工作量的目的&#xff0c;这里就来简单实现一下对excel表…

【办公技巧】如何压缩为rar格式文件?

压缩包格式是我们生活工作中常用到的文件格式&#xff0c;那么如何得到一个rar格式的压缩文件&#xff1f;或者说如何将文件压缩成rar格式而不是zip格式呢&#xff1f;今天我们来了解一下如何压缩为rar格式文件。 首先&#xff0c;想要压缩文件&#xff0c;我们需要压缩软件&a…

【C/C++】实现Reactor高并发服务器 完整版

代码结构 文件介绍 InetAddress.h InetAddress类 ip和端口设置 Socket.h Socket类 设置fd Epoll.h epollfd 管理类 Channel.h Channel类 管理epoll以及对应回调函数实现 EventLoop.h EventLoop事件循环类 TcpServer.h 服务器类 tcpepoll.cpp 主函数 InetAddress.h #if…

uniapp项目准备工作

1.封装请求 export const baseUrl function getHeaders () {let token uni.getStorageSync(token)let header {"access-token":token,// X-Requested-With: XMLHttpRequest,Content-Type: application/json; charsetUTF-8}return header } function reLogin(){/…

【Label Studio运行报错】ModuleNotFoundError: No module named ‘google.rpc‘

报错截图&#xff1a; 解决方法&#xff1a; 新建虚拟环境&#xff0c;安装google相关包 pip install google-cloud-core google-cloud-storage把虚拟环境中site-packages下google文件夹拷贝到当前环境的对应位置下。去官网下载最新的sqlite3&#xff0c;复制到AppData\Loca…

adobe软件提示This non-genuine Adobe app will be disabled soon【软件版本】

因为电脑上级路由器装了小飞机&#xff0c;导致本机电脑ps等adobe的系列软件出现了 This non-genuine Adobe app will be disabled soon&#xff0c;烦人的狠&#xff0c;之前有写过一篇通过更改host的教程&#xff0c;现在已经失效了&#xff0c;今天为大家分享一个用软件来屏…

【嵌入式学习】IO进程线程day02.20

一、思维导图 二、习题 #include <myhead.h> int main(int argc, const char *argv[]) {FILE *fpNULL;FILE *fqNULL;pid_t pidfork();if(pid>0){//在父进程中打开复制文件if((fpfopen("./text.txt","r"))NULL){perror("fopen error");…

职业资格高级执法考试试题及答案,分享几个实用搜题和学习工具 #知识分享#微信

作为当代大学生&#xff0c;我们常常面临着繁重的学业压力和众多的学习任务。在这个信息爆炸的时代&#xff0c;如何高效地进行搜题和学习成了我们迫切需要解决的问题。幸运的是&#xff0c;随着科技的不断进步&#xff0c;我们拥有了许多方便、实用的日常搜题和学习软件。 1.…

解决kkFileView4.4.0版本pdf、word不能预览问题

这里使用的是http下载流url预览&#xff0c;遇到的问题。 官方使用指南&#xff1a;kkFileView - 在线文件预览 1 前端测试代码 1.1 官方示例代码 1.2 本人测试代码 注意&#xff1a;要给预览文件的url进行编码encodeURIComponent(Base64.encode(previewUrl))。 <!DOCTYP…

Spring两大核心思想:IOC和AOP

目录 IOC:控制反转 Ioc概念 Ioc的优点 Spring Ioc AOP:面向切面编程 AOP的优点 Spring AOP 1.添加依赖 2.核心概念 3.通知的类型 4.切点表达式 5.公共切点 pointCut 6.切面优先级 Order 7.使用自定义注解完成AOP的开发 Spring AOP实现有几种方式&#xff1f; S…

Jakarta Bean Validation

Validation 官网 https://beanvalidation.org/ 常见注解 Bean Validation中定义的注解&#xff1a; 注解详细信息Null被注释的元素必须为 nullNotNull被注释的元素必须不为 nullAssertTrue被注释的元素必须为 trueAssertFalse被注释的元素必须为 falseMin(value)被注释的元素…

阿里云幻兽帕鲁服务器,游戏服务端版本升级怎么操作?

用阿里云一键部署的幻兽帕鲁服务器&#xff0c;想要更新游戏服务端版本&#xff0c;现在非常简单。之前还需要通过输入一行命令来更新&#xff0c;而现在可以直接通过面板上的选型来操作。 打开阿里云的计算巢&#xff0c;找到你的这台服务实例&#xff0c;点击进入&#xff0…

【编程题】跳石板

跳石板 分析后可知 要在众多解中寻找最优解 因此用动态规划 比如&#xff1a; 4-6只需跳一步&#xff0c;而6-8也只需一步&#xff0c;因此在刚才跳了一步的基础上再加1 8到10一步&#xff0c;8到12一步&#xff0c;9到12一步&#xff0c;8-10-12两步&#xff0c;因此到12位置…

Stable Diffusion 绘画入门教程(webui)

文章目录 一、前言二、做出的效果三、SD使用流程1、大模型2、关键字3、调参数 一、前言 随着mj和sd绘画软件发布之后&#xff0c;AI绘画开始爆火&#xff0c;很多小伙伴已经挖掘出很多的玩法&#xff0c;哪怕最基础的AI美女、AI壁纸、真人漫改等等都赚的盆满钵满&#xff0c;当…

Nginx 配置详解

官网&#xff1a;http://www.nginx.org/ 序言 Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的。从2004年发布至今&#xff0c;凭借开源的力量&#xff0c;已经接近成熟与完善。 Nginx功能丰富&#xff0c;可作为HTTP服务器&#xff0c;也可作为反向代理服务…

Satoshivm一文科普,手把手教你交互(bitget 钱包)

什么是 SatoshiVM&#xff1f; SatoshiVM 是一种去中心化的第 2 层解决方案&#xff0c;创新地将比特币网络的强大安全性和价值稳定性与以太坊虚拟机 (EVM) 的高级可编程性和灵活性相结合。 SatoshiVM 是区块链领域的一个突出功能&#xff0c;支持使用原生 BTC 作为 Gas&#x…

防火墙——计算机网络

前述基于密码的安全机制不能有效解决以下安全问题&#xff1a; 用户入侵&#xff1a; 利用系统漏洞进行未授权登录&#xff1b; 授权用户非法获取更高级别权限等。 软件入侵&#xff1a; 通过网络传播病毒、蠕虫和特洛伊木马。 拒绝服务攻击等。 解决方法&#xff1a; 防火墙&a…

Leetcode刷题笔记题解(C++):203. 移除链表元素

思路&#xff1a;不同的情况出现了&#xff0c;就是第一个节点要是为等于val的节点&#xff0c;可以新建一个节点&#xff0c;并next指向head&#xff0c;这样就可以遍历新的链表来删除节点 /*** Definition for singly-linked list.* struct ListNode {* int val;* L…

数据库应用:kylin 部署 达梦数据库DM8

目录 一、实验 1.环境 2.部署前规划 3.部署达梦数据库DM8 4.创建数据库及数据库事例管理 5.达梦数据库的基本操作 二、问题 1.xhost命令报错 2.执行安装程序DMInstall.bin 报错 3.解压安装程序报错 4.安装程序找不到文件 5.图像化界面打不开 6.安装内存太小 7.打开…

提升竞争力!攻读在职硕士为职业发展加冕——社科院与杜兰大学金融管理硕士

在现如今竞争激烈的职场环境中&#xff0c;不断提升自身的竞争力是每个职场人士都面临的重要任务。攻读在职硕士学位成为越来越多人实现个人职业发展目标的首选方式之一。特别是社科院与杜兰大学合作开设的金融管理硕士项目&#xff0c;为那些希望在金融行业取得突破的职业人士…