代码随想录第22天|235.二叉搜索树的最近公共祖先,701. 二叉搜索树中的插入操作, 450.删除二叉搜索树中的节点

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

做过二叉树:公共祖先问题 (opens new window)题目的同学应该知道,利用回溯从底向上搜索,遇到一个节点的左子树里有p,右子树里有q,那么当前节点就是最近公共祖先。

后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑。

思路:1.递归法前序遍历

因为是有序树,所有 如果 中间节点是 q 和 p 的公共祖先,那么 中节点的数组一定是在 [p, q]区间的。不用使用回溯,二叉搜索树自带方向性,可以方便的从上向下查找目标区间,遇到目标区间内的节点,直接返回。


class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
      
        if(root.val>p.val&&root.val>q.val){
            //1.说明目标区间在左边
            return lowestCommonAncestor(root.left,p,q);
        }
        else if(root.val<p.val&&root.val<q.val){
            //2.说明目标区间在右边
            return lowestCommonAncestor(root.right,p,q);
        }
        else return root;//3.说明root就在目标区间内
          
    }
}

或者直接用236. 二叉树的最近公共祖先的解答也能AC过去

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

思路

  • 确定终止条件

终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。

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;

到这里,通过递归函数返回值完成了新加入节点的父子关系赋值操作,下一层将加入节点返回,本层用root->left或者root->right将其接住。 

完整代码实现

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {//给定的root是前序遍历的
         //BST适合中序遍历,把val和当前节点的val进行比较
         if(root==null){  // 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
              TreeNode newnode=new TreeNode(val);
              return newnode;

         }
        
         if(root.val>val){//递归创建左子树
             root.left= insertIntoBST(root.left,val);
         }
         if(root.val<val){//递归创建右子树
            root.right=insertIntoBST(root.right,val);
         }
       
   
         return root;


    }
}

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

思路:这道题主要是设计二叉树的节点删除操作之前没有接触过,

采用前序遍历递归的方式

1.递归终止条件:如果没有找到要删除的节点,遍历到空节点就直接返回

2.单层递归逻辑:

A root.val==key, 1.root左子树不为空,那么直接返回右子树;2.root右子树不为空,直接返回左子树;3.root的左右子树不为空,那么把root的左子树嫁接到root的右子树的最底层的最左边

B root.val<key 根据BST的有序性,说明我们要找的目标在当前root节点的右子树

C root.val>key 根据BST的有序性,说明我们要找的目标在当前root节点的左子树

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        //终止条件
        if(root==null){return root;}//情况1,没找都删除的节点,遍历到空节点直接返回
        if(root.val==key){
            //这里有三种情况
            //1.root的左子树不为空,右子树为空
            //2.root的右子树不为空,左子树为空
            //3。root的左右子树都不为空,把root的左子树嫁接到root的右子树的最底层的最左边
            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.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;
        //如果树中不存在key


    }
}

总结

今天都是涉及对BST的操作

235.递归后序遍历,寻找root.val是否在目标区间[p.val,q.val]之间,是则直接return root;否则继续递归

701.将值插入到BST中,如果当前节点root==null,说明我们找到了要插入的位置,直接return newnode;否则(根据给定val和root.val的比较)继续递归左子树和递归右子树

450.大体递归框架和701是一样的,但是在处理root.val=val的情况下又分了五种情况考虑,思考的点是要如何处理要删除的节点的左右子树

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值