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/

发表评论

电子邮件地址不会被公开。