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

题目描述 

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.mzph.cn/news/694570.shtml

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

相关文章

[Android]Frida-hook环境配置

准备阶段 反编译工具:Jadx能够理解Java语言能编写小型的JavaScript代码连接工具:adb设备:Root的安卓机器&#xff0c;或者模拟器 Frida&#xff08;https://frida.re/&#xff09; 就像是你计算机或移动设备的妙妙工具。它帮助你查看其他程序或应用内部发生的事情&#xff0…

pipx — 在隔离环境中安装和运行 Python 应用程序

pipx官网&#xff1a; https://pipx.pypa.io/stable/ pipx pipx 是一个用于安装和运行Python应用程序的工具&#xff0c;它类似于 Linux的 apt 和JavaScript 的 npx 。 pipx和pip的区别&#xff1a; pip是一个通用的python包安装工具pipx专注于安装python cli程序 cli&#…

IP分片重组功能的模拟实现

实现一个IP分片重组的程序涉及到对IP数据报的解析&#xff0c;特别是处理标识、DF&#xff08;Don’t Fragment&#xff09;、MF&#xff08;More Fragments&#xff09;标志、片偏移&#xff08;Fragment Offset&#xff09;和总长度&#xff08;Total Length&#xff09;这几…

Unity坦克炮台永远看向鼠标

Unity坦克炮台永远看向鼠标 原理&#xff1a;射线检测 从屏幕上鼠标的位置&#xff0c;垂直向内发射一条射线&#xff0c;得到射线交互点的坐标&#xff0c;炮台一直看向交互点即可。 代码 public GameObject 炮台; private Ray MouseRay; private RaycastHit MouseRaycast…

117.填充每个节点的下一个右侧节点指针II、104.二叉树的最大深度、111.二叉树的最小深度

题目链接/文章讲解/视频讲解&#xff1a; 代码随想录 1.117.填充每个节点的下一个右侧节点指针II 1.1分析及思路 和116.填充每个节点的下一个右侧节点指针是一样的&#xff0c;我们都用队列&#xff0c;一层一层的指。前n-1个都指向其队列后面的元素。 1.2代码及注释 typed…

TLS、运输层安全协议

目录 运输层安全协议 1 协议 TLS 的要点 1.1 协议 TLS 的位置 1.2 TLS 与应用层协议独立无关 1.3 协议 TLS 具有双向鉴别的功能 1.4 TLS 建立安全会话的工作原理 TLS 的握手阶段 TLS 的会话阶段 1.5 TLS 传送的记录格式 2 协议 TLS 必须包含的措施 运输层安全协议 现…

代码随想录算法训练营|day34

第八章 贪心算法 860.柠檬水找零406.根据身高重建队列452.用最少数量的箭引爆气球代码随想录文章详解 860.柠檬水找零 定义five,ten为顾客付5元和10元的张数&#xff0c;找零时首先找较大面额&#xff0c;分情况讨论&#xff1a; 如果顾客付5元&#xff0c;直接five 如果顾客付…

Python urllib模块学习

HTTP协议 HTTP 协议&#xff1a;一般指HTTP(超文本传输)协议。 HTTP是为Web浏览器和Web服务器之间的通信而设计的&#xff0c;基于TCP/IP通信协议嘞传递数据。 HTTP消息结构 客户端请求消息 客户端发送一个HTTP请求到服务器的请求消息包括以下格式 请求行(request line)请求…

Vue3 (父子组件传参)

父组件通过v-bind&#xff08;简写 :&#xff09;绑定一个数据&#xff0c;然后子组件通过defineProps接受传过来的值。 给Menu组件 传递了一个title 字符串类型是不需要v-bind <template><div class"layout"><Menu title"我是标题">…

Nginx被动健康检测配置

我使用 Nginx 做负载均衡&#xff0c;有时候可能某一台服务器可能会临时出问题&#xff0c;无法访问。这个时候就需要检测服务器是否有问题&#xff0c;这里的检测方式有两种&#xff1a; 1、被动健康检测 就是会判断请求在规定时间内是否报错&#xff0c;如果连续报错多少次…

mysql 2-20

TEXT类型 枚举类型 SET类型 二进制字符串类型 BLOB类型 注意事项 JSON类型 提取数据 空间类型 选择建议 约束

HQYJ 2024-2-21 作业

复习课上内容&#xff08;已完成&#xff09;结构体字节对齐&#xff0c;64位没做完的做完&#xff0c;32位重新都做一遍&#xff0c;课上指定2字节对齐的做一遍&#xff0c;自己验证&#xff08;已完成&#xff09;两种验证大小端对齐的代码写一遍复习指针内容&#xff08;已完…

如何通过本地消息表实现分布式事务?

本地消息表步骤 通过本地消息表&#xff08;也称为可靠消息表&#xff09;实现分布式事务是一种常见的做法&#xff0c;用于保证在分布式环境中消息的可靠传递和事务的一致性。以下是使用本地消息表实现分布式事务的一般步骤&#xff1a; 消息生产方&#xff08;也就是发起方&…

leetcode hot100-1

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…

OpenMVS+Colmap安装

(在home目录下新建一个文件夹library(我给你建好了,解压就行),用来安装各种库文件) 先换源(国外的不用换源) 备份 sudo cp /etc/apt/sources.list /etc/apt/sourses.list_bk修改源 sudo gedit /etc/apt/sources.list将原所有内容删除,添加以下内容: deb http://m…

力扣724. 寻找数组的中心下标(前后缀和)

Problem: 724. 寻找数组的中心下标 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 分别求取nums数组的前、后缀和&#xff08;不包括当前元素&#xff09;&#xff0c;并比较当某个位置的前后缀和相等时&#xff0c;返回该位置&#xff1b; 复杂度 时间复杂度: …

电脑进水无法开机怎么办 电脑进水开不了机的解决方法

意外总是会不定时打破你的计划&#xff0c;电脑这类电器最怕遇到的除了火还有水&#xff0c;设备进水会导致数据丢失&#xff0c;那么我们遇到电脑进水怎么办&#xff1f;进水之后不正确处理也会引起很多不必要的麻烦. 解决办法 第一步&#xff1a;关机 如果您的电脑是在开…

软件测试面试常见问题【含答案】

一、面试技巧题(主观题) 序号面试题1怎么能在技术没有那么合格的前提下给面试官留个好印象&#xff1f;2面试时&#xff0c;如何巧妙地避开不会的问题&#xff1f;面试遇到自己不会的问题如何机智的接话&#xff0c;化被动为主动&#xff1f;3对于了解程度的技能&#xff0c;被…

char型变量中能不能存储一个中文汉字,为什么?(企业真题)

char型变量中能不能存储一个中文汉字&#xff0c;为什么&#xff1f; 可以的。char c1 ‘中’; char c2 ‘a’。 因为char使用的是unicode字符集&#xff0c;包含了世界范围的所有的字符。

软考33-上午题-【知识产权】-计算机软件的商业秘密权

一、商业秘密的定义 不为公众所知悉的&#xff0c;能为权利人带来经济利益、具有实用性并经权利人采取保密措施的技术信息和经营信息。 技术信息和经营信息是商业秘密的基本内容。 二、真题 真题1&#xff1a; 真题2&#xff1a; 申请专利、注册商标。 软件著作权&#xff0…