(二叉树day08) 二叉搜索树的最近公共祖先

一、 二叉搜索树的最近公共祖先

力扣第235题

递归三步走:

1. 确定返回值和参数

        返回的是目标结点,参数是当前结点以及p,q结点,直接用题目给的函数做递归

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)

2. 确定终止条件

        遍历到空结点直接返回

if(root == null) return null;

3. 单层递归的逻辑

        当前结点的值和p,q 值的大小有三种关系

        第一种:root.val > p.val && root.val > q.val (当前节点的值大于p,q结点的值)

                说明p,q结点的最近公共祖先在当前结点的左子树上;

        第二种:root.val < p.val && root.val < q.val (当前节点的值小于p,q结点的值)

                说明p,q结点的最近公共祖先在当前结点的右子树上;

        第三种:当前结点的值介于p,q两者之间

                说明当前节点就是p,q的最近公共最先,直接返回

        if(root.val > p.val && root.val > q.val) {
            return lowestCommonAncestor(root.left, p, q);
        }
        if(root.val < p.val && root.val < q.val) {
            return lowestCommonAncestor(root.right, p, q);
        }
        return root;

整体代码如下:

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) return null;

        if(root.val > p.val && root.val > q.val) {
            return lowestCommonAncestor(root.left, p, q);
        }
        if(root.val < p.val && root.val < q.val) {
            return lowestCommonAncestor(root.right, p, q);
        }
        return root;
    }
}

二、二叉搜索树中的插入操作

力扣第701题

递归三步走:

1. 确定返回值和参数

        返回的是目标结点,参数是当前结点以及 p,val 值,直接用题目给的函数做递归

public TreeNode insertIntoBST(TreeNode root, int val)

2. 确定终止条件

        当访问到空结点时,说明找到了 val 应该存在的位置,返回val结点

if(root == null) return new TreeNode(val);

3. 单层逻辑处理

        当前结点值和目标值 val 的大小有两种关系

        第一种:若当前节点值大于 val ,说明val应该出现在当前节点的左子树上,递归左子树,并用左节点接收递归结果(为什么接收?接受的是终止条件!)

        第二种:若当前节点值小于 val ,说明val应该出现在当前节点的右子树上,递归右子树,并用右节点接收递归结果

        最后,返回当前节点。

        if(root.val > val) {
            root.left = insertIntoBST(root.left, val);
        }
        if(root.val < val) {
            root.right = insertIntoBST(root.right, val);
        }
        return root;

(递归)完整代码如下:

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) return new TreeNode(val);

        if(root.val > val) {
            root.left = insertIntoBST(root.left, val);
        }
        if(root.val < val) {
            root.right = insertIntoBST(root.right, val);
        }
        return root;
    }
}

三、删除二叉搜索树中的节点

力扣第450题:

递归三步走:

1. 确定返回值和参数

public TreeNode deleteNode(TreeNode root, int key)

2.  确定终止条件

        当访问到空结点时,说明访问到边界了,返回空值

if(root == null) return null;

3. 单层处理逻辑

        当找到目标结点时,总共有以下几种情况

        第一种:目标结点为叶子结点,直接返回空值,将其删除

        第二种:目标结点左孩子为空,右孩子不为空,返回右孩子,即目标结点被删除,右孩子补位

        第三种:目标结点右孩子为空,左孩子不为空,返回左孩子,即目标结点被删除,左孩子补位

        第四种:目标节点左右孩子都在,将目标结点左孩子插入到目标结点右孩子的最左边结点的左孩子处,返回目标结点的右孩子

最后:根据当前结点和key的关系进行递归调用,然后返回当前节点

注意:若调用左子树,则用当前结点的左结点指针去接受递归结果,右子树同理

        if(root.val == key) {
            //第一种情况
            if(root.left == null && root.right == null) {
                return null;
            }
            //第二种情况
            if(root.left == null) {
                return root.right;
            }
            //第三种情况
            if(root.right == null) {
                return root.left;
            }
            //第四种情况
            TreeNode node = root.right;
            while(node.left != null) {
                node = node.left;
            }
            node.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;

(递归)完整代码如下:

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.left == null) {
                return root.right;
            }
            //第三种情况
            if(root.right == null) {
                return root.left;
            }
            //第四种情况
            TreeNode node = root.right;
            while(node.left != null) {
                node = node.left;
            }
            node.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;
    }
}

  • 22
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值