6.5 搜索树
This commit is contained in:
parent
566e4136f5
commit
0659fb690e
64
src/main/java/tree/DeleteNode.java
Normal file
64
src/main/java/tree/DeleteNode.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
37
src/main/java/tree/TrimBST.java
Normal file
37
src/main/java/tree/TrimBST.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user