一句话总结:删除二叉搜索树中的节点怪复杂的。
原题链接:235 二叉搜索树的最近公共祖先
有三种办法来解这个问题。首先可以利用236 二叉树的最近公共祖先 的普遍解法来解答。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == root || q == root) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left == null) return right;
if (right == null) return left;
return root;
}
}
以上解法并没有利用到二叉搜索树的性质,将它改造一下,用上二叉搜索树地性质可以更快地找到这个最近公共祖先。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == root || q == root) return root;
if (p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left, p, q);
if (p.val > root.val && q.val > root.val) return lowestCommonAncestor(root.right, p, q);
return root;
}
}
以及最后一种完美利用二叉搜索树性质的解法。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode ans = root;
while (true) {
if (p.val < ans.val && q.val < ans.val) ans = ans.left;
else if (p.val > ans.val && q.val > ans.val) ans = ans.right;
else break;
}
return ans;
}
}
原题链接:701 二叉搜索树中的插入操作
利用好二叉搜索树的性质,因为题中保证了插入的值与树中所有节点的值都不相同,所以一定可以将其作为叶子节点插入树中。
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
TreeNode node = new TreeNode(val);
if (root == null) return node;
TreeNode pos = root;
while (pos != null) {
if (val < pos.val) {
if (pos.left == null) {
pos.left = node;
break;
} else pos = pos.left;
} else {
if (pos.right == null) {
pos.right = node;
break;
} else pos = pos.right;
}
}
return root;
}
}
原题链接:450 删除二叉搜索树中的节点
此题需要考虑多种情况。首先考虑root == null的情况,直接返回root即可。然后是!tree.contains(key)的情况,这需要设计递归的逻辑。最后是找到要删除的节点时的三种情况:该节点仅存在左子树,仅存在右子树,以及左右子树都存在的情况。
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) return root;
if (key == root.val) {
if (root.left == null) return root.right;
if (root.right == null) return root.left;
TreeNode node = root.right;
while (node.left != null) node = node.left;
node.left = root.left;
root = root.right;
}
if (key > root.val) root.right = deleteNode(root.right, key);
if (key < root.val) root.left = deleteNode(root.left, key);
return root;
}
}