【日常训练】450. 删除二叉搜索树中的节点

这篇博客介绍了如何在保持二叉搜索树性质不变的情况下删除给定值的节点。删除操作分为三个步骤:定位节点、判断删除条件及执行删除。示例展示了不同情况下删除节点后的树结构,并提供了一段Java代码实现递归删除功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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

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

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

示例 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, 104].
-105 <= Node.val <= 105
节点值唯一
root 是合法的二叉搜索树
-105 <= key <= 105

代码

/**
 * 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){
            root.right = deleteNode(root.right, key);
            return root;
        }
        // 要删除的点在左子树中...
        if(root.val > key){
            root.left = deleteNode(root.left, key);
            return root;
        }
        // root为要删除的点
        if(root.val == key){
            // 叶子节点 直接删除
            if(root.left == null && root.right == null){
                return null;
            }
            // 该点没有左子树,删除该点,并让右子树替代该点
            if(root.left == null){
                return root.right;
            }
            // 无右子树...
            if(root.right == null){
                return root.left;
            }
            // 既有左子树又有右子树,将其改为符合规范的新树,将其右子树的最小节点作为当前节点
            // 并将其从右子树中删除
            TreeNode suc = root.right;
            while (suc.left != null) {
                suc = suc.left;
            }
            root.right = deleteNode(root.right, suc.val);
            suc.right = root.right;
            suc.left = root.left;
            return suc;
        }
        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值