【陪伴式刷题】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)
相关推荐
夜白宋42 分钟前
【word多文档docx合并】
java·word
@yanyu6661 小时前
idea中配置tomcat
java·mysql·tomcat
2501_916766541 小时前
【项目部署】JavaWeb、MavenJavaWeb项目部署至 Tomcat 的实现方式
java·tomcat
RoboWizard1 小时前
扩容刚需 金士顿新款Canvas Plus存储卡
java·spring·缓存·电脑·金士顿
lang201509281 小时前
Spring Boot 入门:5分钟搭建Hello World
java·spring boot·后端
失散132 小时前
分布式专题——47 ElasticSearch搜索相关性详解
java·分布式·elasticsearch·架构
serve the people2 小时前
LangChain 表达式语言核心组合:Prompt + LLM + OutputParser
java·langchain·prompt
想ai抽2 小时前
深入starrocks-多列联合统计一致性探查与策略(YY一下)
java·数据库·数据仓库
武子康2 小时前
Java-152 深入浅出 MongoDB 索引详解 从 MongoDB B-树 到 MySQL B+树 索引机制、数据结构与应用场景的全面对比分析
java·开发语言·数据库·sql·mongodb·性能优化·nosql
杰克尼2 小时前
JavaWeb_p165部门管理
java·开发语言·前端