235. 二叉搜索树的最近公共祖先
由于是在二叉搜索树中查找最近公共祖先,那么只需要从上到下遍历,遇到当前节点cur的val值在
[p , q]区间内则一定可以说明该节点cur就是 q 和 p 的最近公共祖先。
如图所示,p为节点6,q为节点9
可以看出只需要利用二叉搜索树特性,按指定方向进行遍历,便可以得到最近的公共祖先,并直接返回
完整代码如下:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return null;
if (p.val > q.val) {
// 保证 p.val <= q.val,便于后续情况讨论
return lowestCommonAncestor(root, q, p);
}
if (root.val >= p.val && root.val <= q.val) {
// p <= root <= q
// 即 p 和 q 分别在 root 的左右子树,那么 root 就是 LCA
return root;
}
if (root.val > q.val) {
// p 和 q 都在 root 的左子树,那么 LCA 在左子树
return lowestCommonAncestor(root.left, p, q);
} else {
// p 和 q 都在 root 的右子树,那么 LCA 在右子树
return lowestCommonAncestor(root.right, p, q);
}
}
}
701.二叉搜索树中的插入操作
该题就是分为两步:
1.查找正确应该插入的位置
2.将新节点以返回值的方式插入到父节点上
完整代码如下:
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root == null){
return new TreeNode(val);
}
if(val < root.val){
root.left = insertIntoBST(root.left, val);
}
else if(val > root.val){
root.right = insertIntoBST(root.right, val);
}
return root;
}
}
450.删除二叉搜索树中的节点
该题难点:可能需要调整二叉搜索树的结构
该题目需要删除,也就是先【找】再【删】
所以先写出查找对应节点的代码:
TreeNode deleteNode(TreeNode root, int key) {
if (root.val == key) {
// 找到啦,进行删除
} else if (root.val > key) {
// 去左子树找
root.left = deleteNode(root.left, key);
} else if (root.val < key) {
// 去右子树找
root.right = deleteNode(root.right, key);
}
return root;
}
当查找到所需要删除的节点时又具有3种不同情况:
情况 1:A
恰好是末端节点,两个子节点都为空,那么它可以直接删除。
情况 1 代码:
if (root.left == null && root.right == null)
return null;
情况 2:A
只有一个非空子节点,那么它要让这个孩子接替自己的位置。
情况 2 代码:
// 排除了情况 1 之后
if (root.left == null) return root.right;
if (root.right == null) return root.left;
情况 3:A
有两个子节点,麻烦了,为了不破坏 BST 的性质,A
必须找到左子树中最大的那个节点,或者右子树中最小的那个节点来接替自己。(此时我选择的是找到左子树最大的节点进行接替)
情况 3 代码:
if(root.left != null && root.right != null){
// 获得左子树最大节点
TreeNode maxNode = getMax(root.left);
// 获取当前 root 节点的左子树中寻找并删除左子树中的最大的节点
root.left = deleteNode(root.left, maxNode.val);
// 此时用左子树中的最大值去替换当前 root 节点
maxNode.left = root.left;
maxNode.right = root.right;
root = maxNode;
}
最后整合以上三种情况的代码:
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return null;
if(root.val == key){
// 找到了,进行删除
// 情况1
if(root.left == null && root.right == null) return null;
// 情况2
if(root.left == null) return root.right;
if(root.right == null) return root.left;
// 情况3
if(root.left != null && root.right != null){
// 获得左子树最大节点
TreeNode maxNode = getMax(root.left);
// 获取当前 root 节点的左子树中寻找并删除左子树中的最大的节点
root.left = deleteNode(root.left, maxNode.val);
// 此时用左子树中的最大值去替换当前 root 节点
maxNode.left = root.left;
maxNode.right = root.right;
root = maxNode;
}
}else if(root.val > key){
// 去左子树寻找
root.left = deleteNode(root.left, key);
}else if(root.val < key){
// 去右子树寻找
root.right = deleteNode(root.right, key);
}
return root;
}
public TreeNode getMax(TreeNode node){
// BST中最右侧便是最大的
while(node.right != null){
node = node.right;
}
return node;
}
}