牛客网剑指Offer——二叉搜索树的后序遍历序列

题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

概念

1、二叉搜索树:

二叉搜索树(英语:Binary Search Tree),也称二叉查找树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:

  • 任意节点,如果左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
  • 任意节点,如果右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
  • 任意节点的左、右子树也分别为二叉查找树;
  • 没有键值相等的节点。

2、后序遍历:后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。

方法一

1、由于是后序遍历,遍历顺序为左右根,那么序列的最后一个节点必为根节点;

2、根据二叉搜索树特点:左子树小于根节点,右子树大于根节点,可以很容易根据元素与根节点值大小的比较,找出根节点的左子树及右子树。然后判断左子树节点的值是否都小于根节点的值,右子树节点的值是否都大于根节点的值,判断左右子树对应的序列是否是二叉搜索树的后序遍历的结果。很明显,可以用递归的思路去解决问题 。

代码

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        if( sequence.empty() )
            return false;
        return help( sequence, 0, sequence.size()-1 );
    }
    bool help( vector<int> input, int first, int last )
    {
        if( last-first <= 1 )
            return true;
        int small_last = last-1;
        while( input[small_last] > input[last] )//找左右子树分界点
            small_last--;
        for( int i=first;i<=small_last;i++ )//保证左子树部分都小于root
            if( input[i] > input[last] )
                return false;
        return help(input, first, small_last) && help(input, small_last+1, last-1 );
    }
};

方法二

由于后序遍历以及二叉搜索树的特点,对于序列中每一个节点来说,位于该节点之前的节点,从左到右看,应该是连续的小于该节点值,然后是连续的大于该节点的值,如果出现交叉现象,说明该序列不是二叉搜索树的后序遍历的结果。描述不太清楚,直接看代码就好。

代码

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence)
    {
        int length=sequence.size();
        if(length==0)
            return false;
        int i=0;
        while(--length)
        {
            while(sequence[i++]<sequence[length]);
            while(sequence[i++]>sequence[length]);
            if(i<length)
                return false;
            i=0;
        }
        return true;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36132127/article/details/80200215