题意:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
分析:判断一个序列是否是二叉搜索树的后序遍历,首先由二叉搜索树的性质得知,二叉搜索树的左子节点都比父亲要小,而右子节点都比父亲要大,这时结合后序遍历的特点:左右根,所以我们的策略就是:首先得到一个序列中最后一个元素,当作根,那么接下来寻找左右子树的划分区间,寻找大于当前根的第一个值,那么以这个值为划分,找到了当前根的左右子节点范围,接着进行判断,看它的右子树的值是否都能够大于当前根的值,如果不能,那么这个序列就返回false,如果可以,那么递归向下判断当前根的左右子树是否满足。
特别注意,递归边界的正确性,不要把根设置到判断的范围,否则会造成程序崩溃。
//判断一个序列是否是一个二叉搜索树的后序遍历结果
//首先找到根节点,接着根据二叉搜索树的性质划分左右子树,递归判断左右子树
class Solution {
public:
Solution()
{
}
~Solution()
{
}
bool judge(vector<int>vec,int l,int r)
{
if(r-l+1<=2) return true;
//根节点值
int temp = vec[r];
int i=l;
while(i<r) //注意边界值
{
//找到划分边界
if(vec[i]>temp) break;
i++;
}
for(int j=i;j<r;j++)
{
if(vec[j]<=temp) return false;
}
//此时左右子树均满足要求 递归判断左右子树
bool left = true, right = true;
int leftLength = i-l , rightLength = r-i;
if(leftLength>0) {
left = judge(vec,l,i-1);
}
if(rightLength>0) {
right = judge(vec,i,r-1);
}
return (left&&right);
}
bool VerifySquenceOfBST(vector<int> sequence) {
int len = sequence.size();
if(len<=0) return false;
if(len<=2) return true;
return judge(sequence,0,len-1);
}
};