剑指offer53:二叉搜索树的下一个节点

题目:
给定一棵二叉搜索树和其中的一个节点 p ,找到该节点在树中的中序后继。如果节点没有中序后继,请返回 null 。
节点 p 的后继是值比 p.val 大的节点中键值最小的节点,即按中序遍历的顺序节点 p 的下一个节点。
在这里插入图片描述
输入:root = [5,3,6,2,4,null,null,1], p = 6
输出:null
解释:因为给出的节点没有中序后继,所以答案就返回 null 了。
在这里插入图片描述
输入:root = [2,1,3], p = 1
输出:2
解释:这里 1 的中序后继是 2。请注意 p 和返回值都应是 TreeNode 类型。
分析:
*第一种解法:*解决这个问题最直观的思路就是采用二叉树的中序遍历,因为中序遍历会逐一遍历二叉树的每个节点,如果二叉树有n个节点,那么这种思路的时间复杂度就是O(n),沿用中序非递归遍历模板,在栈出栈的时候判断是否是指定的节点,如果不是就接着循环,如果是则它的下一个节点就是要求的值,因为中序遍历二叉搜索树是递增顺序,所以下一个出栈的节点就是要求的值。
*第二种解法:*换一种思路,通过比较值来查找,从根节点开始,每到一个节点就比较根节点的值和节点p的值,如果当前节点的值小于或等于节点p的值,那么节点p的下一个节点应该在它的右子树,如果当前节点的值大于节点p的值,那么当前节点有可能是它的下一个节点。节点p的下一个节点是所有比它大的节点中值最小的一个,因此接下来将前往当前节点的左子树,确定是否能找到值更小但仍然大于节点p的值的节点。重复这样的比较,直到找到最终结果。
上例子
在这里插入图片描述
比如要找8中序后继,上来先拿头节点8和8比较,相等则右移指针,用变量r把10先保存住,之后再左移指针找到9,r存入9,9大于8,左移为空,所以9是8的后继
比如找10的中序后继,上来拿头节点8和10比较,头节点8比10小,右移指针,找到10,10等于10,右移指针,保存11,11左移为空,因此11就是10的中序后继
代码:

import java.util.Stack;

public class InorderSuccessor {
    public  TreeNode inorderSuccessor1(TreeNode root,TreeNode p){
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        Boolean found = false;
        while (cur !=null && !stack.isEmpty()){
            while (cur!=null){
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if (found = true){
                break;
            }else if (cur == p){
                found = true;
            }
            cur = cur.right;
        }
        return cur;
    }
    public  TreeNode inorderSuccessor2(TreeNode root,TreeNode p) {
        TreeNode cur = root;
        TreeNode result = null;
        while (cur != null) {
            if (cur.val > p.val){
                result = cur;
                cur = cur.left;
            }else {
                cur = cur.right;
            }
        }
        return result;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙崎流河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值