● 235. 二叉搜索树的最近公共祖先
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q);
if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q);
return root;
}
}
函数 lowestCommonAncestor
接收三个参数:
root
:表示二叉搜索树的根节点。p
:表示第一个要查找的节点。q
:表示第二个要查找的节点。
算法的思路是基于二叉搜索树的性质,即对于任意节点,它的左子树的所有节点值都小于它,右子树的所有节点值都大于它。
-
首先判断
root
节点的值与p
和q
的值的关系:- 如果
root
的值同时大于p
和q
的值,说明p
和q
都在root
的左子树中,因此递归调用lowestCommonAncestor
方法在root
的左子树中继续查找。 - 如果
root
的值同时小于p
和q
的值,说明p
和q
都在root
的右子树中,因此递归调用lowestCommonAncestor
方法在root
的右子树中继续查找。
- 如果
-
如果上述两个条件都不满足,说明
root
的值介于p
和q
的值之间,或者root
的值等于p
或q
的值,此时root
就是p
和q
的最低公共祖先,直接返回root
。 -
递归调用的终止条件是
root
为 null,表示在 BST 中未找到p
或q
。
最终,函数会返回 p
和 q
的最低公共祖先节点,即二叉搜索树中离 p
和 q
最近且同时是它们的祖先节点的节点。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while (true) {
if (root.val > p.val && root.val > q.val) {
root = root.left;
} else if (root.val < p.val && root.val < q.val) {
root = root.right;
} else {
break;
}
}
return root;
}
}
● 701.二叉搜索树中的插入操作
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if (root == null) return new TreeNode(val);
TreeNode newRoot = root;
TreeNode pre = root;
while (root != null) {
pre = root;
if (root.val > val) {
root = root.left;
} else if (root.val < val) {
root = root.right;
}
}
if (pre.val > val) {
pre.left = new TreeNode(val);
} else {
pre.right = new TreeNode(val);
}
return newRoot;
}
}
● 450.删除二叉搜索树中的节点
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
root = delete(root,key);
return root;
}
private TreeNode delete(TreeNode root, int key) {
if (root == null) return null;
if (root.val > key) {
root.left = delete(root.left,key);
} else if (root.val < key) {
root.right = delete(root.right,key);
} else {
if (root.left == null) return root.right;
if (root.right == null) return root.left;
TreeNode tmp = root.right;
while (tmp.left != null) {
tmp = tmp.left;
}
root.val = tmp.val;
root.right = delete(root.right,tmp.val);
}
return root;
}
}
-
public TreeNode deleteNode(TreeNode root, int key)
: 删除二叉搜索树中值为key
的节点,函数的入参为树的根节点root
和要删除的节点值key
。 -
if (root == null) return root;
: 如果当前节点为空,即已经遍历到树的叶子节点或者目标节点不存在于树中,则直接返回当前节点。 -
if (root.val == key) { ... }
: 如果当前节点值等于目标节点值key
,则执行删除操作。 -
if (root.left == null) { return root.right; } else if (root.right == null) { return root.left; }
: 如果当前节点只有一个子节点(左子节点或右子节点),则直接将子节点替代当前节点。 -
else { ... }
: 如果当前节点有两个子节点,则执行复杂的删除操作。 -
TreeNode cur = root.right;
: 创建一个临时节点cur
,并将其初始化为当前节点的右子节点,用于寻找右子树中的最左节点。 -
while (cur.left != null) { cur = cur.left; }
: 在右子树中寻找最左节点,即找到右子树中的最小值节点。 -
cur.left = root.left;
: 将找到的最左节点的左子节点指向当前节点的左子节点,以保留当前节点的左子树。 -
root = root.right;
: 将当前节点指向其右子节点,即删除当前节点。 -
return root;
: 返回更新后的子树的根节点。如果当前节点是目标节点,则返回删除后的根节点;如果当前节点不是目标节点,则继续递归地在左右子树中删除目标节点。