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日

相关推荐

  • leetcode108-将有序数组转换为二叉搜索树

    原题 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。 示例: 给定有序数…

    算法 2020年1月18日
    090
  • leetcode105-从前序与中序遍历序列构造二叉树

    原题 根据一棵树的前序遍历与中序遍历构造二叉树。 注意:你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inord…

    算法 2020年1月13日
    090
  • leetcode141-环形链表

    原题 给定一个链表,判断链表中是否有环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没…

    2019年12月14日
    0100
  • leetcode125-验证回文串

    原题 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 说明: 本题中,我们将空字符串定义为有效的回文串。 示例 1: 输入: "A man, a …

    算法 2020年5月21日
    0140
  • leetcode225--用队列实现栈

    原题 使用队列实现栈的下列操作: push(x) – 元素 x 入栈 pop() – 移除栈顶元素 top() – 获取栈顶元素 empty() – 返回栈是否为空 注意: 你只能…

    算法 2019年12月13日
    0120
  • leetcode365-水壶问题

    原题 有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水? 如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升…

    算法 2020年3月21日
    0190
  • leetcode652-寻找重复的子树

    原题 给定一棵二叉树,返回所有重复的子树。对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。 两棵树重复是指它们具有相同的结构以及相同的结点值。 示例1: 1 / \ 2…

    算法 2019年12月26日
    0310
  • 数组元素左右两边最近较小元素

    原题(来源牛客网) 给定一个不含有重复值的数组 arr,找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i] 小的位置。返回所有位置相应的信息。 实例: 输入: ar…

    算法 2020年4月26日
    0700
  • leetcode887-鸡蛋掉落

    原题 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。 你知道存在楼层 F ,满足 0 &…

    算法 2020年4月11日
    0120
  • 剑指offer17-打印从1到最大的n位数

    原题(来源Leetcode) 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。 示例 1: 输入: …

    算法 2020年4月17日
    080

发表回复

登录后才能评论