Day 22 | 235. 二叉搜索树的最近公共祖先 & 701.二叉搜索树中的插入操作 & 450.删除二叉搜索树中的节点

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

解题思路:

        利用二叉搜索树特性,最近公共祖先数值大小一定位于p和q的数值之间,(或者就是p或q本身)。

因此遍历节点时:

p和q数值都大于当前节点,则该节点数值过小,向遍历。

p和q数值都小于当前节点,则该节点数值过大,向遍历。

        以上情况都不符合,包含两种情况:

①当前遍历的节点数值位于p和q数值之间,则该节点为最近公共祖先,返回该节点

②当前遍历节点数值大于/小于 p和q之间的一个节点,则该节点就是p/q之中的另一节点。该节点为最近公共祖先,返回该节点

 递归法:

        直接向左右子树递归遍历即可,不需要遍历中间节点。

        当遍历到空节点时,说明不存在最近公共祖先,返回null即可。

    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); return left;}
        else if(root.val<p.val && root.val<q.val){TreeNode right=lowestCommonAncestor(root.right,p,q); return right;}
        return root; 
    }

迭代法:

        当遍历节点不为空时,一直想左右子树遍历直到为空/找到停止。

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while(root!=null){
            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{
                return root;
            }
        }
        return root;
    }

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

递归解题思路:

        利用搜索二叉树特性,当val小于当前节点数值时,则val位于该节点的左侧。反之在右侧。因此自顶向上遍历可以一直递归遍历,一定可以将val插入在当前树的叶子结点中。

        当遍历到空节点时,则代表此处为即将要插入的叶子结点。创建一个新节点存放val,并返回该节点作为其上一个节点的子树即可。然后将结果一直向上返回直至根节点。

    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.删除二叉搜索树中的节点

        这道题挺难的哈哈哈,勉强看懂。 

解题思路:

        首先,本题有五种情况:

①没找到被删除节点(后面四种都是找到的情况)

②被删除节点左右子树都为空,直接返回null

③当左子树为空,返回右子树

④当右子树为空,返回左子树

⑤最复杂的情况:被删除节点的左右子树都不为空。

        此时根据搜索二叉树的特性,当节点被删除后,其左子树可以连接在其右子树的最左侧叶子结点上。反之亦然。

递归解法:

        当前遍历节点数值大时,删除的节点一定在当前节点左侧,因此要修改root.left的值。返回删除好的子树作为当前节点的左子树。反之亦然。最后将结果层层递归返回到根节点上。成为一个新的二叉搜索树。

    public TreeNode deleteNode(TreeNode root, int key) {
        //第一种情况:没找到,返回null
        if(root==null){return root;}
        //当前遍历节点数值大时,删除的节点一定在当前节点左侧,因此要修改root.left的值。返回删除好的子树作为当前节点的左子树
        if(root.val>key){root.left=deleteNode(root.left,key);}  
        //反之亦然
        if(root.val<key){root.right=deleteNode(root.right,key);} 
        
        else if(root.val==key){
            //第二、三种情况:当左子树为空,返回右子树(当右子树也为空时同样返回右子树——null)
            if(root.left==null){
                return root.right;
            //第四种情况:右子树为空,返回左子树
            }else if(root.right==null){
                return root.left;
            }else{
            //第五种情况,左右都不为空 —— 将被删除节点的左子树作为右子树的最左侧叶子
            //令cur指向被删除右子树的最左侧叶子结点
                TreeNode cur=root.right;
                while(cur.left!=null){
                    cur=cur.left;
                }
            //将被删除节点的左子树连接在cur的左子树上
                cur.left=root.left;
            //返回root的右子树,作为root父节点的新右子树。
                root=root.right;
                return root;
            }
        }
        return root;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值