【陪伴式刷题】Day 20|二叉树|450.删除二叉搜索树中的节点(Delete Node in a BST)

刷题顺序按照代码随想录建议

题目描述

英文版描述

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.

Basically, the deletion can be divided into two stages:

  1. Search for a node to remove.
  2. If the node is found, delete the node.

Example 1:

Input: root = [5,3,6,2,4,null,7], key = 3 Output: [5,4,6,2,null,null,7] Explanation: Given key to delete is 3. So we find the node with value 3 and delete it. One valid answer is [5,4,6,2,null,null,7], shown in the above BST. Please notice that another valid answer is [5,2,6,null,4,null,7] and it's also accepted.

Example 2:

Input: root = [5,3,6,2,4,null,7], key = 0 Output: [5,3,6,2,4,null,7] Explanation: The tree does not contain a node with value = 0.

Example 3:

Input: root = [], key = 0 Output: []

Constraints:

  • The number of nodes in the tree is in the range [0, 10^4].
  • -10^5 <= Node.val <= 10^5
  • Each node has a unique value.
  • root is a valid binary search tree.
  • -10^5 <= key <= 10^5.

英文版地址

leetcode.com/problems/de...

中文版描述

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

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

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

示例 1:

输入: root = [5,3,6,2,4,null,7], key = 3 输出: [5,4,6,2,null,null,7] 解释: 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。 另一个正确答案是 [5,2,6,null,4,null,7]。

示例 2:

输入: root = [5,3,6,2,4,null,7], key = 0 输出: [5,3,6,2,4,null,7] 解释: 二叉树不包含值为 0 的节点

示例 3:

输入: root = [], key = 0 输出: []

提示:

  • 节点数的范围 [0, 10^4].
  • -10^5 <= Node.val <= 10^5
  • 节点值唯一
  • root 是合法的二叉搜索树
  • -10^5 <= key <= 10^5

中文版地址

leetcode.cn/problems/de...

解题方法

递归法

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
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 root.right;
            }else if (root.left != null && root.right == null) {
                return root.left;
            }else if (root.left == null && root.right == null) {
                return null;
            }else {
                TreeNode right = root.right;
                while (right.left != null) {
                    right = right.left;
                }
                right.left = root.left;
                return root.right;
            }
        }
        if (root.val > key) {
            root.left = deleteNode(root.left, key);
        }
        if (root.val < key) {
            root.right = deleteNode(root.right, key);
        }
        return root;
    }
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是二叉树的节点数,每一个节点恰好被遍历一次
  • 空间复杂度:O(n),为递归过程中栈的开销,平均情况下为 O(log⁡n),最坏情况下树呈现链状,为 O(n)

迭代法

迭代法的关键在于保存当前遍历节点的父节点,这样才能删除它

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        TreeNode cur = root;
        TreeNode parent = null;
        while (cur != null && cur.val != key) {
            if (cur.val < key) {
                parent = cur;
                cur = cur.right;
            } else {
                parent = cur;
                cur = cur.left;
            }
        }
        if (cur == null) {
            return root;
        } else if (cur.right == null && cur.left == null) {
            cur = null;
        } else if (cur.right != null && cur.left == null) {
            cur = cur.right;
        } else if (cur.right == null && cur.left != null) {
            cur = cur.left;
        } else {
            TreeNode r = cur.right;
            if (r != null) {
                while (r.left != null) {
                    r = r.left;
                }
                r.left = cur.left;
                cur = cur.right;
            }
        }
        if (parent == null) {
            return cur;
        }
        if (parent != null && parent.left != null && parent.left.val == key) {
            parent.left = cur;
        }
        if (parent != null && parent.right != null && parent.right.val == key) {
            parent.right = cur;
        }

        return root;
    }
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是二叉树的节点数,每一个节点恰好被遍历一次
  • 空间复杂度:O(1)
相关推荐
一线大码几秒前
Java 使用国密算法实现数据加密传输
java·spring boot·后端
我命由我123456 分钟前
Android Gradle - Gradle 自定义插件(Build Script 自定义插件、buildSrc 自定义插件、独立项目自定义插件)
android·java·java-ee·kotlin·android studio·android-studio·android runtime
Riu_Peter10 分钟前
【技术】Maven 配置 settings.xml 轮询下载
xml·java·maven
十六年开源服务商42 分钟前
2026年WordPress网站地图完整指南
java·前端·javascript
Edward111111111 小时前
3月17枚举
java·开发语言
凡。。。2961 小时前
阿里云产品说明
java
蓝天守卫者联盟11 小时前
2026乙酸乙酯回收设备厂家选型与技术实践
java·jvm·python·算法
于先生吖1 小时前
教育数字化转型 JAVA 国际版答题练习系统完整开发教程
java·开发语言
lakernote1 小时前
EasyPostman 重大更新:正式支持插件模式,当前已上线 5 个官方插件
java·测试工具·开源·postman