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;
}
}
思路:
-
基本情况:
-
如果当前
root
节点的值大于p
和q
的值,那么p
和q
都在root
的左子树中,因此我们将递归在左子树中查找。 -
如果当前
root
节点的值小于p
和q
的值,那么p
和q
都在root
的右子树中,因此我们将递归在右子树中查找。
-
-
结束条件:
- 如果
root
的值不满足上述两种情况,那么root
要么与p
相等,要么与q
相等,或者root
的值在p
和q
之间。在这三种情况下,root
节点都是p
和q
的最低公共祖先。
- 如果
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if (root == null) // 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
return new TreeNode(val);
if (root.val < val){
root.right = insertIntoBST(root.right, val); // 递归创建右子树
}else if (root.val > val){
root.left = insertIntoBST(root.left, val); // 递归创建左子树
}
return root;
}
}
思路:
-
首先检查当前的
root
节点是否为空。如果为空,这意味着我们已经找到了一个合适的位置来插入val
。因此,我们创建一个新的节点,将val
的值赋给它,并返回这个新创建的节点。 -
如果当前
root
节点的值小于val
,这意味着val
应该被插入到root
的右子树中。所以,我们递归调用insertIntoBST
,将root.right
和val
作为参数。这样我们就能继续在右子树中查找val
的正确位置。 -
如果当前
root
节点的值大于val
,这意味着val
应该被插入到root
的左子树中。所以,我们递归调用insertIntoBST
,将root.left
和val
作为参数。这样我们就能继续在左子树中查找val
的正确位置。 -
在递归调用之后,我们需要更新当前
root
节点的左子节点或右子节点,以指向新插入的节点(如果有的话)。 -
最后,返回当前的
root
节点。
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) return root;
if (root.val == key) {
if (root.left == null) {
return root.right;
} else if (root.right == null) {
return root.left;
} else {
TreeNode cur = root.right;
while (cur.left != null) {
cur = cur.left;
}
cur.left = root.left;
root = root.right;
return root;
}
}
if (root.val > key) root.left = deleteNode(root.left, key);
if (root.val < key) root.right = deleteNode(root.right, key);
return root;
}
}
思路:
-
如果
root
为空,直接返回null
。这是基本的递归结束条件。 -
如果当前
root
的值等于要删除的key
值,这意味着我们找到了要删除的节点。接下来有三种情况:-
当前节点没有左子树,返回右子树。这也包括了当前节点既没有左子树也没有右子树的情况。
-
当前节点没有右子树,返回左子树。
-
当前节点既有左子树又有右子树。这种情况下,我们需要找到一个替代的节点来替换当前要删除的节点。替代的节点可以是左子树的最大值节点或右子树的最小值节点。在这段代码中,它选择了右子树的最小值节点。因此,它遍历右子树直到找到最左侧的节点(即最小值),然后将要删除节点的左子树连接到这个最小值节点的左子树上。最后,返回
root
的右子树。
-
-
如果当前
root
的值大于key
,这意味着要删除的节点在左子树中,因此递归调用deleteNode
函数处理左子树。 -
如果当前
root
的值小于key
,这意味着要删除的节点在右子树中,因此递归调用deleteNode
函数处理右子树。 -
在所有情况下,最后返回的是
root
节点。