【陪伴式刷题】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)
相关推荐
myNameGL21 分钟前
linux安装idea
java·ide·intellij-idea
青春男大23 分钟前
java栈--数据结构
java·开发语言·数据结构·学习·eclipse
HaiFan.1 小时前
SpringBoot 事务
java·数据库·spring boot·sql·mysql
我要学编程(ಥ_ಥ)1 小时前
一文详解“二叉树中的深搜“在算法中的应用
java·数据结构·算法·leetcode·深度优先
music0ant1 小时前
Idea 添加tomcat 并发布到tomcat
java·tomcat·intellij-idea
计算机徐师兄2 小时前
Java基于SSM框架的无中介租房系统小程序【附源码、文档】
java·微信小程序·小程序·无中介租房系统小程序·java无中介租房系统小程序·无中介租房微信小程序
源码哥_博纳软云2 小时前
JAVA智慧养老养老护理帮忙代办陪诊陪护小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
chenziang12 小时前
leetcode hot100 对称二叉树
算法·leetcode·职场和发展
忒可君3 小时前
C# winform 报错:类型“System.Int32”的对象无法转换为类型“System.Int16”。
java·开发语言
斌斌_____3 小时前
Spring Boot 配置文件的加载顺序
java·spring boot·后端