题解 | #JZ23二叉搜索树的后序遍历序列# 值得多写

二叉搜索树的后序遍历序列

http://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd

二叉搜索树

定义

二叉搜索树是一种节点值之间具有一定数量级次序的二叉树,对于树中每个节点:

若其左子树存在,则其左子树中每个节点的值都不大于该节点值;
若其右子树存在,则其右子树中每个节点的值都不小于该节点值。

示例:

图片说明

题解:

可以利用 二叉搜索树的根节点是左右节点限制这个条件 , 从最底部开始判断。

由于一个正确的遍历序列,我们可以在它任意一个位置故意篡改,因此势必要遍历所有的元素才能确定它的正确性,所以个人认为,这个问题的时间复杂度下界应该就是O(n)。

具体来说,二叉搜索树的关键特征是:对于任意一棵子树,均有“左子树<根节点<右子树”,因此,它的根节点约束了它左右子树的取值范围,二叉搜索树的根root是它左子树值的上限(max),同时是它右子树值的下限(min)。如果我们从根节点出发往下走,那么高层祖辈节点序列就会不停地对低层未遍历节点形成一个上下限约束,只要低层节点没有违背这个约束,那么它就是合法的,否则,序列就是不合法的。

因为后序遍历的一些特性,我们可以从右到左倒序访问给定的序列,因为后序遍历的最后一个元素是根节点,倒序访问就相当于是从根到叶,从右到左的访问顺序,从根到叶可以让我们利用祖辈节点提供的上下限约束信息来判断孩子节点合法性,具体步骤如下:

如果当前元素 > 上一个元素,这说明当前元素可能是上一个元素的右孩子,这时候:
如果当前元素突破max上限约束,说明祖辈中存在 “左子树 > 根” 的情况,违背了搜索树的定义(尝试把图中4的值换成7,那么就有子辈7 > 祖辈max约束5,搜索树不成立);
否则,当前元素就是上一个元素的右孩子,当前元素将成为新的祖辈节点,为后续节点提供约束;

如果当前元素 < 上一个元素,这就说明当前元素是某个祖辈节点的左孩子,这时候:
我们需要找出这个祖辈节点,并将该祖辈的右子树节点全部丢弃(因为它的右子树结构已经确定,无法为后续节点提供帮助),该祖辈节点的值将成为新的max上限约束,当前元素将成为新的祖辈节点,继续为后续节点提供约束;

图片说明

因此,我们需要使用一个栈来存储已经确定了的祖辈节点,当新节点的合法性被确定时,入栈,当算法需要寻找当前节点是谁的左孩子时,出栈;

图片说明

import java.util.Stack;

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length<1) return false;

        Stack<Integer> roots = new Stack<>();
        roots.push(Integer.MIN_VALUE);
        int max = Integer.MAX_VALUE;

        for(int i=sequence.length-1;i>-1;i--){

            if(sequence[i]>max) return false;

            while(sequence[i]<roots.peek()){ //这里使用while,栈中存着顶到底 大到小的数据, 非常巧妙,多练几遍。
                max = roots.pop();
            }

            roots.push(sequence[i]);
        }

        return true;
    }
}
全部评论

相关推荐

感觉这一周太梦幻了,就像一个梦,很不真实~~~感觉这个暑期,我的运气占了99成,实力只有百分之一4.15上午&nbsp;腾讯csig&nbsp;腾讯云部门,面完秒进入复试状态4.16下午&nbsp;美团优选供应链部门,4.18上午发二面4.17晚上&nbsp;阿里国际一面,纯拷打,面完我都玉玉了4.18下午&nbsp;阿里国际二面,是我们leader面的我,很轻松~~4.18晚上&nbsp;约了hr面4.19上午&nbsp;hr面,下午两点口头oc4.19晚上&nbsp;意向书说起来我的暑期好像一次都没挂过~~~~~难道我是天生面试圣体?----------------------------------------------------------------------六个月前,我还是0项目0刷题,当时想的是先把论文发出来再去找实习。结果一次组会,老师打破了我的幻想(不让投B会,只让投刊或者A)我拿头投啊!!!然后就开始物色着找实习,顺便做完了mit的6.s081,但是基本上还是没刷过题目-----------------------------------------------------------------------11月&nbsp;&nbsp;一次偶然的机会,面进了某个耳机厂的手环部门,大概是做嵌入式的,用的是CPP。12月&nbsp;莫名其妙拿到了国创的面试机会,0基础四天速成java基础!居然也给我面过了hhhhh,可能是面试没写题吧入职国创后的几个月,一直没活,天天搁那看剧,都快忘了还有暑期实习这回事了~~~~命运的齿轮在2.26开始转动,因为这一天美团开了,我开始慌了,因为那时的我什么都不会。lc,八股,sql全部是0进度。然后就开始了女娲补天,上班刷题,下班继续做之前的开源,顺便学一学八股。3月到现在,lc也刷到快200了,一天最多提交了47次~~~~~~~~~~八股根据别人的面经总结和博客,写了快十万字的笔记~~~~~~~~~~简历上的实习经历和开源,也努力去深挖了,写了几万字的记录~~~~~~所以面试的时候,基本上都能cover了,面试官问到的基础基本都会,不基础的我就把他往我会的地方引。结果好像还不错,基本上每个面试官评价都挺好的emmmmmmmm
投递阿里巴巴等公司10个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务