代码随想录刷题记录day20 二叉搜索树的最近公共祖先+二叉搜索树中的插入操作+删除二叉搜索树中的节点

代码随想录刷题记录day20 二叉搜索树的最近公共祖先+二叉搜索树中的插入操作+删除二叉搜索树中的节点

参考:代码随想录

235. 二叉搜索树的最近公共祖先

在这里插入图片描述

思想

1.用普通二叉树的思想去做了这道题目 和昨天的题解类似

2.利用二叉搜索树的特性

可以不用遍历整棵二叉搜索树了,搜索的是一条边,搜索到了就可以直接返回

如果当前节点 小于p 大于q,那么当前节点就是要找的公共祖先

如何理解这一点呢?如下图所示,只要第一次遇到了 就是最近的公共的祖先
在这里插入图片描述

代码
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //因为是一颗二叉搜索树 利用二叉搜索数的特性实现

        if(root==null) return null;
        
        if(root.val>p.val &&root.val>q.val){
            TreeNode left=lowestCommonAncestor(root.left,p,q);
            if(left!=null) return left;
        }
        if(root.val<p.val && root.val<q.val){
            //p q都比当前节点大  在右边
            TreeNode right=lowestCommonAncestor(root.right,p,q);
            if(right!=null) return right;
        }

        return root;

    }

701. 二叉搜索树中的插入操作

在这里插入图片描述

思想

二叉搜索树可以永远插在叶子节点。

根据这个特性遍历到最终要插入的位置

递归终止条件 root==null 表示 遍历到了要插入的节点了,新建一个节点,同时向上返回,被root的左节点 或者root的右节点去接住这个节点。

具体左节点去接还是右节点去接住呢?比较数值的大小,利用二叉搜索树的特性,

val<root.val 左节点接住

val>root.val 右节点接住

单层递归的逻辑:

1.当前节点的值大于要插入的值,那么要往左递归,且用当前节点的左节点去接住递归的结果

2.当前节点的值小于要插入的值,要往右递归,用当前节点的右节点去接住递归的结果

3.向上返回当前的节点

代码
class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        //插入新的节点 可以在叶子节点插入
        if(root==null) {
            TreeNode node=new TreeNode(val);
            return node;//向上返回这个要插入的节点。
        }

        if(root.val>val){
            //当前节点的值大于要插入的节点 那么要插入的位置肯定是在左边
            root.left =insertIntoBST(root.left,val);
        }
        if(root.val<val){
            root.right=insertIntoBST(root.right,val);
        }

        return root;
    }
}

450. 删除二叉搜索树中的节点

在这里插入图片描述

思想

删除节点的逻辑写在终止条件当中,又分为了5中情况

1.没找到要删除的节点 返回null

找到了要删除的节点

2.左右都为空,即找到了叶子节点 返回null

3.左空 右不为空 返回右节点

4.左不为空右为空 返回左节点

5.左右都不为空,找到右节点最左边的值cur, 让当前节点root的左子树移到cur的左子树 ,此时变成了左为空,右不为空的情况,返回右节点。

单层递归逻辑:

当前节点值大于要删除的值,那么要删除的节点就在左边,往左递归,同时需要接住删除节点后的左子树

右边也是一样的逻辑

在这里插入图片描述

代码
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        //删除节点的情况分为5中
        if(root==null) return null;//1.没找到要删除的节点
        if(root.val==key){
            if(root.left==null && root.right==null){
                //2.找到了叶子节点
                return null;
            }
            else if(root.left!=null && root.right==null){
                //3.左不为空 右为空的情况
                return root.left;
            }
            else if(root.left==null && root.right!=null){
                //4.左为空 右不为空
                return root.right;
            }
            else{
                //左右都不为空的情况  找到右节点的最左边的值  让这个值成为父节点
                TreeNode cur=root.right;
                while(cur.left!=null) {
                    cur=cur.left;
                }
                cur.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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值