LeetCode—450. Delete Node in a BST

LeetCode—450. Delete Node in a BST

题目

https://leetcode.com/problems/delete-node-in-a-bst/
删除搜索二叉树中的一个节点,返回新的搜索二叉树,因为结果不唯一,任意返回一个即可。

解析及代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    /** 
    使用迭代的话删除那个节点之后还需要重新连接其父节点指针, 也就是需要记录父节点. 这样的话就变得很麻烦, 因为还有一些特殊的情况, 
    比如要删除的节点是根节点, 或者还需要记录 当前节点是父节点的左子树还是右子树. 
    在此时递归就体现了其优越性, 因为递归是可以回溯的, 所以不需要记录父节点. 然后考虑删除以后节点的替换
    
    递归的方法 分情况讨论
    因为是用递归,我们先来看root是否是要铲除的节点
    如果不是,我们要看是要删除左子树还是右子树上的节点,判断方法就是比较大小了,接着递归就行了
    然后如果root是要删除的节点,这就要进一步分情况了
        如果root的左子树或者右子树有一个是空的,那么简单,直接返回另一个不为空的子树就行了
        如果root的左右子树都是空,那么也简单,说明是叶子节点,直接返回空
        如果root的左右子树都不为空,这就比较麻烦,并且这时候新的搜索二叉树不唯一,我们选右子树的最小值作为新树的根节点的值
            在这种情况下,我们先把右子树的最小值复制到root,然后可以这样想,我们可以把这种情况看做左子树为空右子树不为空的情况,
            我们要进行的操作是递归操作中的删除右子树,只不过这时候的key值变成了我们选择的右子树的最小值了
            至于右子树的最小值如何找到,那就是利用搜索树的性质,最小值在左子树上
    */
    public TreeNode deleteNode(TreeNode root, int key) {
        if(root==null) return null;
        if(root.val>key){
            root.left = deleteNode(root.left, key);
            return root;
        }else if(root.val<key){
            root.right = deleteNode(root.right, key);
            return root;
        }else{
            if(root.left==null || root.right==null)
                return root.left!=null ?  root.left:root.right;
            else{
                TreeNode cur = root.right;
                System.out.println("1");
                while(cur.left!=null)
                    cur = cur.left;
                root.val = cur.val;
                root.right = deleteNode(root.right, cur.val);
                return root;
            }
            
        }
    }
}

猜你喜欢

转载自blog.csdn.net/pnnngchg/article/details/87911083