算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 删除二叉搜索树中的节点,我们先来看题面:

https://leetcode-cn.com/problems/delete-node-in-a-bst/

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.

Basically, the deletion can be divided into two stages:

Search for a node to remove.

If the node is found, delete the node.

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

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

首先找到需要删除的节点;

如果找到了,删除它。

示例


解题

https://blog.csdn.net/xxx_gt/article/details/103673563

首先是利用一个递归函数,每次排除1/2子树的节点,跟我上面的中序遍历相比,大大提高了效率。

递归函数,有两个要点要理解,一个是递归函数的作用,二是它返回的结果是什么。这道题里,这个递归函数的作用就是 删除一棵树里的目标节点,返回的是这棵修改后的树的根节点root。

递归过程:

deleteNode(root, key)

如果根节点的值大于目标节点key的值,说明key在左子树,所以递归调用(root.left, key)。key在左子树,也就说明 只用修改左子树就行了,右子树不用动,所以可以使 root.left = deleteNode(root.left, key).

如果根节点的值小于目标节点key的值,说明key在右子树,所以递归调用(root.right, key)。同理,rot.rght = deleteNode(root.right, key).

如果根节点的值等于目标节点key的值,说明找到key了,开始进行下一步处理。

(启示:说到 二叉搜索树BST时,不仅要想到中序遍历的结果是排好序的,还要想到可以递归,有点像二分查找的模式寻找目标值,提高效率)

删除节点:

经过上一步的递归过程,找到了key,而且key是要调整的这个子树的根节点。

(思考1:竟然不用存储pre节点,是怎么做到连接两个部分的树的?)

当遍历到这个节点时,其实变量名只是起到一个指针的作用,直接修改它的值就行,直接令它的值等于它的继承节点的值。

调整子树:

这部分用到两个子函数:

def successor(root): # 代表中序遍历序列的后一个节点,即比当前节点大的最小节点

root = root.right

while root.left:

root = root.left

return root.val

def predecessor(root): # 代表中序遍历序列的前一个节点,即比当前节点小的最大节点

root = root.left

while root.right:

root = root.right

return root.val

要分三种情况:

整个子树就只有一个节点,也就是根节点是叶节点,这是直接令其等于None就行了。

根节点有右子树,继承节点就选择 它的后一个节点(比目标节点大的最小节点)。

root.val = successor(root) # 用它的后继节点代替它

root.right = self.deleteNode(root.right, root.val) # 修改右子树

根节点无右子树但有左子树,继承节点就选择 它的前一个节点(比目标节点小的最大节点)。

root.val = predecessor(root) # 用它的后继节点代替它

root.left= self.deleteNode(root.left, root.val) # 修改右子树

代码如下:

class Solution:def deleteNode(self, root: TreeNode, key: int) -> TreeNode:if not root:return Nonedef successor(root): # 代表中序遍历序列的下一个节点,即比当前节点大的最小节点root = root.rightwhile root.left:root = root.leftreturn root.valdef predecessor(root):root = root.leftwhile root.right:root = root.rightreturn root.valif key > root.val: # 如果key大于根节点,则从右子树寻找root.right = self.deleteNode(root.right, key)elif key < root.val: # 如果key小于根节点,则从左子树寻找root.left = self.deleteNode(root.left, key)else: # key == 根节点if not root.left and not root.right: # 如果根节点是叶节点,则直接删除该节点return  Noneif root.right: # 如果该节点有右节点,则要找比它大的下一个节点(后继节点)root.val = successor(root) # 用它的后继节点代替它root.right = self.deleteNode(root.right, root.val)else:root.val = predecessor(root)root.left = self.deleteNode(root.left, root.val)return root

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。

上期推文:

LeetCode1-440题汇总,希望对你有点帮助!

LeetCode刷题实战441:排列硬币

LeetCode刷题实战442:数组中重复的数据

LeetCode刷题实战443:压缩字符串

LeetCode刷题实战444:序列重建

LeetCode刷题实战445:两数相加 II

LeetCode刷题实战446:等差数列划分 II - 子序列

LeetCode刷题实战447:回旋镖的数量

LeetCode刷题实战448:找到所有数组中消失的数字

LeetCode刷题实战449:序列化和反序列化二叉搜索树

​LeetCode刷题实战450:删除二叉搜索树中的节点相关推荐

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

    文章目录 LeetCode 236. 二叉树的最近公共祖先 题目讲解 思路 LeetCode 701.二叉搜索树中的插入操作 题目讲解 思路 LeetCode 450.删除二叉搜索树中的节点 题目讲解 ...

  2. 二叉树part8 | ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

    文章目录 235. 二叉搜索树的最近公共祖先 思路 代码 困难 701.二叉搜索树中的插入操作 思路 代码 450.删除二叉搜索树中的节点 思路 代码 困难 今日收获 235. 二叉搜索树的最近公共祖 ...

  3. leetcode 450. 删除二叉搜索树中的节点 c语言实现

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

  4. 67. Leetcode 450. 删除二叉搜索树中的节点 (二叉搜索树-基本操作类)

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

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

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

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

    参考 二叉搜索树删除操作 要删除节点有2子节点,找到右子树中最小的节点,将其val值覆盖要删除的节点值,再删除这个最小节点 要删除的节点的子节点为1个或0个,直接将要删除的节点的父节点指向子的子节点 ...

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

    var deleteNode = function(root, key) {//没找到if(root==null){return root}//找到了if(root.val==key){//1,没有子 ...

  8. LeetCode450题—— 删除二叉搜索树中的节点

    首先需要认识什么是二叉搜索树,可以进入百度词条https://baike.baidu.com/item/%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91/70 ...

  9. 【数据结构与算法】之深入解析“删除二叉搜索树中的节点”的求解思路与算法示例

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

最新文章

  1. ALD对照CVD淀积技术的优势
  2. 我的Java开发学习之旅------gt;Java经典排序算法之希尔排序
  3. PLSQL导出Oracle表结构
  4. 跟正刊学习SCI英文写作——摘要部分的拆解
  5. 入门顶点动画纹理的实例化绘制
  6. python语言画心_python语言还是java如何用python画爱心
  7. 怎样高速读懂别人的项目
  8. import torch报错 from torch._C import * ImportError: DLL load failed: 找不到指定的程序。解决办法
  9. NFNet的学习笔记
  10. C/C++算法竞赛代码框架
  11. POJ 2955 Brackets(区间DP)
  12. 树莓派-12-投屏秒变家庭影院kodi跨平台媒体播放器
  13. EtherCAT中AX58100烧写xml文件的说明(2)-TwinCAT软件安装
  14. 用slmgr命令激活正版Win7旗舰版系统
  15. 戴尔服务器怎么u盘安装win7系统教程,戴尔电脑怎么用u盘装win7系统教程
  16. 社区购物、社区买菜小程序源码
  17. vue路由传参 params传参不能传对象
  18. window10 20H2安卓模拟器VT检测不到问题解决方法
  19. [附源码]计算机毕业设计JAVA音乐网站
  20. markdown语法之表格

热门文章

  1. RET RETF IRET IRETD 指令的不同
  2. MySQL数据库(基础)
  3. 牛津3000词汇表(The Oxford 3000™)
  4. 钉钉企业内部开发工具配置
  5. android 获取栈顶activity,android获取当前栈顶的activity
  6. BS工作原理—BS总结
  7. 关于Java程序员技能和面试注意事项
  8. 对接支付宝当面付,记录过程
  9. img ,background-img,background-size
  10. linux 存储映射lun 给_LINUX系统下添加映射存储LUN