From 0659fb690e7914f342e6a6682431f91dcfb9a896 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Thu, 5 Jun 2025 11:00:40 +0800 Subject: [PATCH] =?UTF-8?q?6.5=20=E6=90=9C=E7=B4=A2=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/tree/DeleteNode.java | 64 ++++++++++++++++++++++++++++++ src/main/java/tree/TrimBST.java | 37 +++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/main/java/tree/DeleteNode.java create mode 100644 src/main/java/tree/TrimBST.java diff --git a/src/main/java/tree/DeleteNode.java b/src/main/java/tree/DeleteNode.java new file mode 100644 index 0000000..1985247 --- /dev/null +++ b/src/main/java/tree/DeleteNode.java @@ -0,0 +1,64 @@ +package tree; +/** + * 题目:450. 删除二叉搜索树中的节点 (deleteNode) + * 描述:给定一个二叉搜索树的根节点 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]。 + + * 链接:https://leetcode.cn/problems/delete-node-in-a-bst/ + */ +//不会 +public class DeleteNode { + public TreeNode deleteNode(TreeNode root, int key) { + if (root == null) { + // 没找到,直接返回 null + return null; + } + + if (key < root.val) { + // 待删除节点在左子树 + root.left = deleteNode(root.left, key); + } else if (key > root.val) { + // 待删除节点在右子树 + root.right = deleteNode(root.right, key); + } else { + // 找到要删除的节点 root + + // 情况 1 & 2:只有 0 个或 1 个子节点 + if (root.left == null) { + // 用右子树替代当前节点(右子树可能为 null 或者是一个节点) + return root.right; + } else if (root.right == null) { + // 用左子树替代当前节点 + return root.left; + } + + // 情况 3:左右子节点都存在 + // 找到右子树的最小节点(中序后继) + TreeNode successor = findMin(root.right); + // 用后继节点的值覆盖当前节点 + root.val = successor.val; + // 在右子树中删除这个后继节点(它要么是叶子,要么只有右子节点) + root.right = deleteNode(root.right, successor.val); + } + + // 返回删除结束后当前子树的根 + return root; + } + + // 辅助函数:在以 node 为根的子树中找到最小节点(一直往左即可) + private TreeNode findMin(TreeNode node) { + while (node.left != null) { + node = node.left; + } + return node; + } +} diff --git a/src/main/java/tree/TrimBST.java b/src/main/java/tree/TrimBST.java new file mode 100644 index 0000000..f5a5109 --- /dev/null +++ b/src/main/java/tree/TrimBST.java @@ -0,0 +1,37 @@ +package tree; +/** + * 题目:669. 修剪二叉搜索树 (trimBST) + * 描述:给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。 + * 修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。 + * 所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。 + * + * 示例 1: + 输入:root = [1,0,2], low = 1, high = 2 + 输出:[1,null,2] + + * 链接:https://leetcode.cn/problems/trim-a-binary-search-tree/ + */ +//不会 +public class TrimBST { + public TreeNode trimBST(TreeNode root, int low, int high) { + if (root == null) { + return null; + } + + // 情况一:当前节点值过小,左子树都小于它 => 整个左子树都可丢弃 + if (root.val < low) { + return trimBST(root.right, low, high); + } + + // 情况二:当前节点值过大,右子树都大于它 => 整个右子树都可丢弃 + if (root.val > high) { + return trimBST(root.left, low, high); + } + + // 情况三:当前节点值在区间 [low, high] 内,需要保留, + // 但左右子树仍需递归修剪 + root.left = trimBST(root.left, low, high); + root.right = trimBST(root.right, low, high); + return root; + } +}