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

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

参考:代码随想录

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

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

思想

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

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

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

如果当前节点大于p 大约q ,那么就往左子树去遍历 ,需要接住返回值,返回的是公共节点,再层层向上返回

如果当前节点小于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. 二叉搜索树中的插入操作

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

思想

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

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

递归终止条件 root==null 表示 遍历到了要插入的节点了,新建一个节点,同时向上返回,

单层递归的逻辑:

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

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

代码

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

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

思想

删除节点的逻辑写在终止条件当中,又分为了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;
    }
}

你可能感兴趣的:(算法,leetcode)