今日收获:二叉搜索树的最近公共祖先,插入操作,删除节点
1. 二叉搜索树的最近公共祖先
题目链接:235. - 力扣(LeetCode)
思路:和求二叉树的最近公共祖先不同,这道题可以充分利用二叉搜索树的特性。根据root和两个节点的值判断,如果都大于两个节点,则结果在root左区间,反之亦然;如果root在区间中,则结果是root。
方法:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 结果在root的左区间
if (root.val>p.val&&root.val>q.val){
return lowestCommonAncestor(root.left,p,q);
}
// 结果在root的右区间
if (root.val<p.val&&root.val<q.val){
return lowestCommonAncestor(root.right,p,q);
}
// root在两个值中间
return root;
}
}
总结:二叉搜索树中,在两个节点值区间的节点一定是最近公共祖先
2. 二叉搜索树的插入操作
题目链接:701. - 力扣(LeetCode)
思路:根据当前节点的值和插入值来判断插入位置。如果当前节点的值大于插入值,说明应该插入当前节点的左边。如果左子树为空,则插入左节点;否则递归调用方法,插入当前节点的左子树
方法:
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if (root==null){
return new TreeNode(val);
}
// 插入左边
if (root.val>val){
if (root.left!=null){
insertIntoBST(root.left,val);
}else {
root.left=new TreeNode(val);
}
}
// 插入右边
if (root.val<val){
if (root.right!=null){
insertIntoBST(root.right,val);
}else {
root.right=new TreeNode(val);
}
}
return root;
}
}
3. 删除二叉搜索树中的节点
题目链接:450. - 力扣(LeetCode)
思路:如果删除当前节点,根据当前节点是否有左右孩子做不同处理,如果左右孩子都有,则当前节点的左孩子变成右孩子最左边节点的左孩;否则比较当前节点的值和目标值,分别交给左右子树处理
方法:
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root==null){
return null;
}
// 删除当前节点
if (root.val==key){
// 叶子节点
if (root.left==null&&root.right==null){
return null;
}
// 只有左孩子
if (root.right==null){
return root.left;
}
// 只有右孩子
if (root.left==null){
return root.right;
}
// 左右孩子都有
// 根节点的左孩子变成右孩子最左边节点的左孩子
TreeNode maxleft=root.right;
while (maxleft.left!=null){
maxleft=maxleft.left;
}
maxleft.left=root.left;
return root.right;
}
// 交给左右子树
if (root.val>key){
root.left=deleteNode(root.left,key);
}
if (root.val<key){
root.right=deleteNode(root.right,key);
}
return root;
}
}