LeetCode.255 Verify Preorder Sequence in Binary Search Tree(验证先序遍历是否符合二叉搜索树,剑指Offer原题)

1.验证先序遍历:

题目:

Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary search tree.

You may assume each number in the sequence is unique.

Follow up: Could you do it using only constant space complexity?

思路:

题目意思是给定一个数组,检查这个数组是否是一个二叉搜索树的先序遍历。

可以知道,数组的第一个值为跟几点,往后如果是降序,这说明在向左遍历,如果开始升序,则说明在向右遍历。(升序与降序相对于根节点)。

举一个例子分析编程思路:

给定数组是【10,5,2,6,12】和【10,5,2,6,12,9】,正确的二叉搜索树是:

    10
   /  \
  5    12
 / \
2   6
用栈暂存降序路径,初始化最小值min为系统最小值,开始判断10,比最小值大,而且栈为空,所以将10入栈----》判断5,比最小值大,入栈--》判断2,比最小值小,入栈-----》判断6,6比当前最小值min大,但是比栈顶元素大,说明开始升序向右走了,所以将2出栈,并且min设置为2;此时栈顶元素为5,仍旧比6小,所以将5出栈,min设置为5;栈顶变为10,比6大,则将6入栈-------》判断12,同上,比栈顶6大,10大,升序部分,出栈,最终min设置为10,12入栈。如果此时出现9,因为升序部分说明12之前的最小值是10,那么12之后的数据应该都比10大,如果是9,不满足这种情况,说明此数组不是二叉搜索树的先序遍历。


可知,min记录的是开始上升阶段前的里升点最近的最小值。以此判断此后的值都比此最小值大。这是条件限制点。


分析:

package LeetCode;

import java.util.Stack;

public class LeetCode_255 {
    public static void main(String[] args) {
        int [] nums={10,5,2,6,12,9};
        System.out.println(verifyPreorde(nums));
    }
    public static  boolean verifyPreorde(int [] nums){
        //验证前序遍历是否符合二叉搜索树
        //思路:初始化min为Integer.MIN_VALUE(),同时使用一个stack记录之前数据,保证每次栈顶数据大于当前对比值,使用min变量记录每次上升阶段最小的,以此判断此后的值都比该值大

        int min=Integer.MIN_VALUE;
        Stack <Integer> stack = new Stack <>();
        for(int num:nums){
            if(num<min){
                return false;
            }
            //当栈不为空时,每次对比数大于栈顶元素,min更新为之前栈顶元素
            while(!stack.isEmpty()&&num>stack.peek()){
                min=stack.pop();
            }

            //将元素进栈
            stack.push(num);

        }
        return true;
    }
}

2.验证中序遍历:

思路:

根据中序遍历可知,left-root-right.只需要判断数组是否是升序即可

3.验证后续遍历:

思路:

后序序列的顺序是left - right - root,而先序的顺序是root - left - right。

我们同样可以用本题的方法解,不过是从数组的后面向前面遍历,因为root在后面了。而且因为从后往前看是先遇到right再遇到left,所以我们要记录的是限定的最大值,而不再是最小值,栈pop的条件也变成pop所有比当前数大得数。栈的增长方向也是从高向低了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值