首页 > 其他分享 >删除二叉搜索树中的节点(力扣450)

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

时间:2024-04-04 23:33:41浏览次数:21  
标签:结点 删除 450 root 二叉 力扣 null 树中 节点


文章目录


题目

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

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

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

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

在这里插入图片描述

前知

二叉搜索树是什么?

二叉搜索树(Binary Search Tree,简称BST)是一种常用的二叉树结构,它具有以下性质:

  1. 左子树的节点值小于根节点的值:每个节点都有一个左子树,且左子树中的所有节点的值都小于该节点的值。
  2. 右子树的节点值大于根节点的值:每个节点都有一个右子树,且右子树中的所有节点的值都大于该节点的值。
  3. 左右子树也是二叉搜索树:左子树和右子树也分别满足以上两个性质,即它们也是二叉搜索树。

由于二叉搜索树的这些性质,它具有很多有用的特性,其中最重要的是可以在平均O(log n)的时间复杂度内进行搜索、插入和删除操作。这是因为在一个平衡的二叉搜索树中,每次操作都会将搜索范围减半,从而实现了快速的查找。
二叉搜索树常被用于实现集合、映射等数据结构,也被广泛用于算法设计和实现中。然而,需要注意的是,如果二叉搜索树不平衡,即树的高度过高,搜索、插入和删除操作的时间复杂度可能会退化为O(n),这时可能需要进行平衡操作来维持其性能。


题解

一、思路

在这个题目中,我们需要实现一个函数来删除二叉搜索树中的指定节点,并且保持二叉搜索树的性质。想要删除二叉搜索树中的结点比增加结点更有难度,增加只需要找到叶子结点,在尾部添加即可,不用改变树的结构

而删除结点分为5种情况,第一种是没有找到删除的结点,遍历到空结点直接返回空;第二种情况是找到删除的结点,并且是叶子结点;第三种情况是找到删除的结点,当前结点为左空右不空的情况;第四种情况是找到删除的结点,当前结点为右空左不空的情况;第五种情况是找到删除的结点,当前结点为左右都不空的情况。然后递归的父结点去接收递归得到的结果,最后返回根节点

二、解题方法

递归三部曲

1. 确定递归函数的参数和返回值
首先确定参数为树的根结点和要删除的值,返回值为树结点

public TreeNode deleteNode(TreeNode root, int key)

2. 确定终止条件
终止条件为删除时的条件有五种情况

  1. 未找到删除结点返回null
if(root == null ) {
            return null;
        }
  1. 删除结点为叶子结点,返回null
if(root.left == null && root.right == null){
                return null;
            }
  1. 删除结点只有左孩子没有右孩子,返回删除结点的左孩子
if(root.left == null && root.right != null){
                return root.left;
            }
  1. 删除结点只有右孩子没有左孩子,返回删除结点的右孩子
if(root.left != null && root.right == null){
                return root.right;
            }
  1. 删除结点左右孩子都有,最复杂的情况,先让cur指向删除结点的右孩子,一直循环找右子树中最左的左孩子为cur,把要删除结点的左子树全部移到循环找到的cur的左孩子里,返回删除结点的右部分即可

第五种情况如果难以理解,可以结合下面的动画,将删除节点(元素7)的左孩子放到删除节点(元素7)的右子树的最左面节点(元素8)的左孩子上,就是把5为根节点的子树移到了8的左孩子的位置。要删除的节点(元素7)的右孩子(元素9)为新的根节点。.
450.删除二叉搜索树中的节点.gif
此图片取自Carl老师代码随想录

3. 确定单层递归的逻辑
只需根据二叉搜索树的顺序判断要删除的值与当前结点的大小去遍历整棵树,如果删除的值大于当前结点,说明要删除的结点在右子树里,反之,再将递归得到的子树用左右孩子接收,再返回根结点。

三、Code

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null ) {
            return null;
        }
        if(root.val == key){
            if(root.left == null){
                return root.right;
            }
            else if(root.right == null){
                return root.left;
            }else{
                TreeNode cur = root.right;
                while(cur.left != null){
                    cur = cur.left;
                }
                cur.left = root.left;
                // root = root.right;
                return root.right;
            }
        }
        if(root.val < key){
            root.right = deleteNode(root.right,key);
        }
        if(root.val > key){
            root.left = deleteNode(root.left,key);
        }
        return root;
    }
}

总结

以上就是对力扣第450题的解题思路和代码实现,需要注意的是最关键也是最复杂的第五种情况(删除一个左右孩子都不为空的节点)。删除结点操作是通过递归的返回值来实现的,在递归的上一层接住我们递归得到的子树返回值。
希望本文对你理解和解决这道题有所帮助!

标签:结点,删除,450,root,二叉,力扣,null,树中,节点
From: https://blog.csdn.net/Huahua_1223/article/details/137177725

相关文章

  • 分发饼干(力扣455)
    文章目录题目贪心算法思想概述关键要素解题步骤优缺点优点缺点应用领域题解一、思路二、解题方法三、Code总结题目Problem:455.分发饼干假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子i,都有一个胃口值g......
  • Offer必备算法21_回文串dp_六道力扣题详解(由易到难)
    目录①力扣647.回文子串解析代码②力扣5.最长回文子串解析代码③力扣1745.分割回文串IV解析代码④力扣132.分割回文串II解析代码⑤力扣516.最长回文子序列解析代码⑥力扣1312.让字符串成为回文串的最少插入次数解析代码本篇完。①力扣647.回文子串64......
  • 代码随想录算法训练营第二十一天| 530. 二叉搜索树的最小绝对差 501. 二叉搜索树中的
    530.二叉搜索树的最小绝对差https://leetcode.cn/problems/minimum-absolute-difference-in-bst/description/TreeNodepre=null;intres=Integer.MAX_VALUE;publicintgetMinimumDifference(TreeNoderoot){if(root==null)return0;pr......
  • 力扣每日一题:LCR112--矩阵中的最长递增路径
    题目给定一个 mxn 整数矩阵 matrix ,找出其中 最长递增路径 的长度。对于每个单元格,你可以往上,下,左,右四个方向移动。 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)。示例1:输入:matrix=[[9,9,4],[6,6,8],[2,1,1]]输出:4解释:最长递增路径为 [1......
  • 2024.3.8力扣每日一题——找出美丽数组的最小和
    2024.3.8题目来源我的题解方法一数学题目来源力扣每日一题;题序:2834我的题解方法一数学经过分析,在target之前,取小于等于target/2的正整数才能使得和最小,并且满足条件3。时间复杂度:O(n)空间复杂度:O(n)publicintminimumPossibleSum(intn,inttarget)......
  • leetcode每日一题 1379. 找出克隆二叉树中的相同节点
    问题描述给你两棵二叉树,原始树original和克隆树cloned,以及一个位于原始树original中的目标节点target。其中,克隆树cloned是原始树original的一个副本。请找出在树cloned中,与target相同的节点,并返回对该节点的引用(在C/C++等有指针的语言中返回节点指针,其他......
  • LeetCode-1379. 找出克隆二叉树中的相同节点【树 深度优先搜索 广度优先搜索 二叉树】
    LeetCode-1379.找出克隆二叉树中的相同节点【树深度优先搜索广度优先搜索二叉树】题目描述:解题思路一:递归,由于我们比较的是节点而不是节点值(例如C++比较的是地址),所以下面的代码也适用于树中有值相同节点的情况(本题的进阶问题)。解题思路二:递归这题有几个关键点,一:判......
  • 力扣
    目录题目法一、模拟法二、规律题目给定一个非负整数num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。示例1:输入:num=38输出:2解释:各位相加的过程为:38-->3+8-->1111-->1+1-->2由于2是一位数,所以返回2。示例2:输入:num=0输......
  • 力扣热门算法题 322. 零钱兑换,344. 反转字符串,347. 前 K 个高频元素
    322.零钱兑换,344.反转字符串,347.前K个高频元素,每题做详细思路梳理,配套Python&Java双语代码,2024.04.02 可通过leetcode所有测试用例。目录322.零钱兑换解题思路完整代码PythonJava​编辑344.反转字符串解题思路完整代码PythonJava​编辑347.前K个高频......
  • 力扣热门算法题 349. 两个数组的交集,387. 字符串中的第一个唯一字符,394. 字符串解码
    349.两个数组的交集,387.字符串中的第一个唯一字符,394.字符串解码,每题做详细思路梳理,配套Python&Java双语代码,2024.04.02 可通过leetcode所有测试用例。目录349.两个数组的交集解题思路完整代码PythonJava387.字符串中的第一个唯一字符解题思路完整代码Python......