leetcode450-删除二叉搜索树中的节点

原题

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

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

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

说明: 要求算法时间复杂度为 O(h),h 为树的高度。

示例:

root = [5,3,6,2,4,null,7] key = 3

    5
   / \
  3   6
 / \    \
2   4   7

给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。

一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。

    5
   / \
  4   6
 /     \
2       7

另一个正确答案是 [5,2,6,null,4,null,7]。

    5
   / \
  2   6
   \   \
    4   7

解法

思想

删除一个节点,可以有三种情况:

  1. 它没有子节点,那么直接删除。
  2. 它拥有一个子节点,那么直接用子节点替换它
  3. 它有两个子节点,则可以:

将它的右子节点附在左子节点的最右边:

leetcode450-删除二叉搜索树中的节点

或,将它的左子节点附在右子节点的最左边:

leetcode450-删除二叉搜索树中的节点

实际就是让搜索树线性化,这样操作会让搜索树的高度逐渐失衡,所以并不推荐作为一个数据结构这样实现。

更好的删除方法可以参考官方题解: https://leetcode-cn.com/problems/delete-node-in-a-bst/solution/shan-chu-er-cha-sou-suo-shu-zhong-de-jie-dian-by-l/

代码

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){
                TreeNode node = root.left;
                while(node.right!=null){
                    node = node.right;
                }
                node.right = root.right;
                return root.left;
            }else return root.right;
        }
        if(root.left!=null&&root.left.val==key){//左子节点是要删除的节点
            if(root.left.left==null && root.left.right==null) root.left = null;
            else if(root.left.left!=null){
                TreeNode node = root.left.left;
                while(node.right!=null){
                    node = node.right;
                }
                node.right = root.left.right;
                root.left = root.left.left;
            }else root.left = root.left.right;
        }else if(root.right!=null&&root.right.val==key){//右子节点是要删除的节点
            if(root.right.left==null && root.right.right==null) root.right = null;
            else if(root.right.right!=null){
                TreeNode node = root.right.right;
                while(node.left!=null){
                    node = node.left;
                }
                node.left = root.right.left;
                root.left = root.right.right;
            }else root.right = root.right.left;
        }else {
            deleteNode(root.left,key);
            deleteNode(root.right,key);
        }
        return root;
    }
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode450-%e5%88%a0%e9%99%a4%e4%ba%8c%e5%8f%89%e6%90%9c%e7%b4%a2%e6%a0%91%e4%b8%ad%e7%9a%84%e8%8a%82%e7%82%b9/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年1月16日
下一篇 2020年1月17日

相关推荐

  • leetcode705-设计哈希集合

    原题 不使用任何内建的哈希表库设计一个哈希集合 具体地说,你的设计应该包含以下的功能 add(value):向哈希集合中插入一个值。 contains(value) :返回哈希集合…

    算法 2019年12月18日
    0140
  • leetcode209-长度最小的子数组

    原题 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。 示例: 输入: s = …

    算法 2019年11月20日
    0170
  • 剑指offer64-求1+2+…+n

    原题(来源Leetcode) 求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。 示例1…

    算法 2020年6月2日
    0550
  • leetcode57-插入区间

    原题 给出一个无重叠的 ,按照区间起始端点排序的区间列表。 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 示例 1: 输入: …

    算法 2020年5月12日
    0280
  • leetcode27-移除元素

    原题 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(…

    算法 2019年11月20日
    080
  • leetcode530-二叉搜索树的最小绝对差

    原题 给定一个所有节点为非负值的二叉搜索树,求树中任意两节点的差的绝对值的最小值。 示例: 输入:    1    &n…

    算法 2020年2月22日
    01330
  • leetcode914-卡牌分组

    原题 给定一副牌,每张牌上都写着一个整数。 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌。 组内所有的牌上都写着相同的整数。…

    算法 2020年3月27日
    0100
  • leetcode543-二叉树的直径

    原题 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。 示例: 给定二叉树 1 / \ 2 3 / \ 4 5…

    算法 2020年3月10日
    0210
  • leetcode385-迷你语法分析器

    原题 给定一个用字符串表示的整数的嵌套列表,实现一个解析它的语法分析器。 列表中的每个元素只可能是整数或整数嵌套列表 提示: 你可以假定这些字符串都是格式良好的: 字符串非空 字符…

    算法 2020年1月28日
    02260
  • 海量数据去重-由BitMap引出的布隆过滤器

    本文参考资源: 那些惊艳的算法们(一)——布隆过滤器_C/C++_xinzhongtianxia的博客-CSDN博客 详解布隆过滤器的原理、使用场景和注意事项 - 简书 概述 昨天…

    2020年2月28日
    01.3K0

发表回复

登录后才能评论