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

题目描述:

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。

假设输入的数组的任意两个数字都互不相同。

样例

输入:[4, 8, 6, 12, 16, 14, 10]

输出:true

分析:

 分析下BST后序遍历的性质,比如4,8,6,12,16,14,10。毫无疑问10是根结点,由于是BST,左子树严格小于根结点严格小于右子树,所以4,8,6为左子树,12,16,14为右子树。

我们递归的来解决这个问题,首先,边界情况,一个结点肯定满足BST的性质。我们从左往右遍历后序序列,遇见的第一个大于根结点的说明后面的序列都是右子树,继续遍历,如果还发现小于根结点的元素,则必定不是BST。接着继续考察左右子树是否也满足上述性质。该算法时间复杂度为O(n^2),如果想要线性的时间复杂度,就需要牺牲空间了。我们对后序遍历序列排一下序,然后由后序和中序序列如果能够构建一颗二叉树,那么便合法。

注意:我们知道,一颗二叉树的中序序列是递增的,那么这颗二叉树必然是BST。由二叉树的中序序列和前序或者后序序列能够唯一的确定一棵二叉树,前提是这些序列一定合法,不是所有的序列我们都可以构建一棵二叉树。

由一个已经确定的长度为n的前序序列,我们可以构建出Catalan(n)棵二叉树,而中序序列有n!种情况。比如n为3;前序序列为1,2,3,可以构造出4*5*6/(2*3)/4=5种不同的二叉树,而3!为6,说明有一种中序序列是不合法的,也就是312不合法(与栈混洗的312禁形类似),说明我们完全也可以用栈混洗的方法来求这一题。

class Solution {
public:
    bool verifySequenceOfBST(vector<int> sequence) {
        int n = sequence.size();
        if(!n)    return true;
        return isBST(sequence,0,n - 1);
    }
    bool isBST(vector<int> s,int l,int r){
        if(l >= r)  return true;
        int i;
        for(i = l;i < r;i++){
            if(s[i] > s[r]) break;
        }
        for(int j = i;j < r;j++){
            if(s[j] < s[r]) return false;
        }
        return isBST(s,l,i-1) && isBST(s,i,r-1);
    }
};

猜你喜欢

转载自blog.csdn.net/qq_30277239/article/details/88345015