LeetCode Java刷题笔记— 450. 删除二叉搜索树中的节点

Posted 刘Java

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode Java刷题笔记— 450. 删除二叉搜索树中的节点相关的知识,希望对你有一定的参考价值。

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

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

中等难度。有两种方式一种是递归,另一种是非递归。

我们首先要找到被值相同的节点A:

  1. 如果该节点的一个子树为空,那么用另一个子树的根节点代替当前节点的位置即可。

  2. 如果该节点的两个子树都为空,那么删除该节点即可,这就是第一种情况的特例。

  3. 如果该节点的左右子树都不为null,那么找到左子树的最大节点或者右子树的最小节点B,此时剩下的步骤有两个思路

    1. 第一种是方法是将A的左子树赋值给B的左子树(如果B是右子树的最小节点),或者将A的右子树赋值给B的右子树(如果B是左子树的最大节点)。
    2. 另一种方法是将找到的节点B的值赋给节点A,然后删除找到的节点B,这样的好处是不会增加树的层级。

迭代算法:

public TreeNode deleteNode(TreeNode root, int key) 

    if (root == null) 
        return null;
    
    //node 值相等的节点  pre 被删除节点的前驱节点  removeNode 真正被删除的节点
    TreeNode node = root, pre = null, removeNode = root;
    while (node != null) 
        //找到了key相等的节点
        if (node.val == key) 
            //开始查找真正需要删除的节点
            removeNode = node;
            //查找左子树的最大节点
            if (removeNode.left != null && removeNode.right != null) 
                pre = removeNode;
                removeNode = removeNode.left;
                while (removeNode.right != null) 
                    pre = removeNode;
                    removeNode = removeNode.right;
                
            
            break;
        
        pre = node;
        node = node.val > key ? node.left : node.right;
    
    //如果没找到,那么返回root
    if (node == null) 
        return root;
    
    //交换值,然后删除真正需要被删除的节点
    node.val = removeNode.val;
    if (pre != null) 
        if (removeNode == pre.left) 
            pre.left = removeNode.left != null ? removeNode.left : removeNode.right;
        
        if (removeNode == pre.right) 
            pre.right = removeNode.left != null ? removeNode.left : removeNode.right;
        
        return root;
    
    root = removeNode.left != null ? removeNode.left : removeNode.right != null ? removeNode.right : null;
    return root;

递归算法,更好理解,就是一个dfs递归遍历:

public TreeNode deleteNode(TreeNode root, int key) 
    if (root == null) 
        return null;
    
    if (root.val > key) 
        root.left = deleteNode(root.left, key);
     else if (root.val < key) 
        root.right = deleteNode(root.right, key);
     else 
        //1 2 该节点的至少一个子树为空,返回另一个子树
        if (root.left == null || root.right == null)
            return root.left != null ? root.left : root.right != null ? root.right : null;
        else 
            //3 该节点的左右子树都不为null

            //查找右子树的最小节点p
            TreeNode p = root.right;
            while (p.left != null) 
                p = p.left;
            
            //root的左子树赋值给p的左子树
            p.left = root.left;
            root = root.right;
            return root;
        
    
    return root;

以上是关于LeetCode Java刷题笔记— 450. 删除二叉搜索树中的节点的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode刷题笔记-数据结构-day16

[JavaScript 刷题] 树 - 删除二叉搜索树中的节点, leetcode 450

[JavaScript 刷题] 树 - 删除二叉搜索树中的节点, leetcode 450

leetcode刷题总结401-450

LeetCode Java刷题笔记汇总

LeetCode Java刷题笔记—226. 翻转二叉树