题目描述:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
例如在下面的一颗二叉搜索树中,输入数组{5,7,6,9,11,10,8},则返回true,因为这个整数序列是下图二叉搜索树的后序遍历结果。如果输入的数组是{7,4,6,5},由于没有哪棵二叉搜索树的后序遍历的结果是这个序列,因此返回false。
解题思路:
【后序遍历的特点】:
在后序遍历得到的序列中,最后一个数字是树的根结点的值。数组中前面的数字可以分为两部分:第一部分是左子树结点的值,它们都比根结点的值小;第二部分是右子树结点的值,它们都比根结点的值大。
1. 通过取出序列最后一个元素得到二叉搜索树的根节点;
2. 在二叉搜索树中找到第一个大于根节点的位置index,因此左子树的区间为[0, index-1],右子树的区间为[index, length-1];
4. 重复以上步骤递归判断左右子树是不是二叉搜索树,如果都是,则返回true,如果不是,则返回false。
Demo:
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence)
{
int sz = sequence.size();
if (sz == 0)
return false;
int *a = new int[sequence.size()];
for (int i = 0; i < sz; ++i)
a[i] = sequence[i];
return fun(a, sz);
delete []a;
}
bool fun(int *sequence, int length)
{
int root = sequence[length - 1];
int i = 0;
// 搜索第一个大于根节点的结点
for (; i < length -1; ++i)
{
if (sequence[i] > root)
break;
}
int j = i;
// 在i之后如果有小于root的结点说明不符合二叉搜索树的定义
for (; j < length -1; ++j)
{
if (sequence[j] < root)
return false;
}
bool left = true, right = true;
if (i > 0)
// 递归遍历左子树区间
left = fun(sequence, i);
if (i < length -1)
// 递归遍历右子树区间
right = fun(sequence + i, length - i - 1);
return (left && right);
}
};