题目:输入一个正数数组,判断该数组是不是某二叉查找树的后序遍历结果。如果是,返回true,如果不是返回false
思路:
1.分治法:
分解:找到一个pivot,判断p到pivot结点以及pivot到q-1结点的两个子序列是否满足条件。
合并:当两个子序列满足条件后,判断第一个子序列的结点是否都小于根结点,第二个子序列的结点是否等大于根结点。
2.如何找到该pivot。
后序遍历结果根结点在最后,那么从最后一个序列开始往前,找到第一个小于该结点的结点,令其为pivot。当发现只要满足该条件后第二个子序列必然满足条件,所以需要判断第一个子序列是否都小于根结点。
代码如下:
int findPivot(int*a ,int p ,int q){
int ele = a[q];
int i=q-1;
for (;i>=p;i--)
{
if (a[i]<ele)
{
break;
}
}
return i;
}
bool isPosTree(int*a, int p, int q){
if (a==NULL)
{
return false;
}
if (p<q)
{
int r = findPivot(a,p,q);//该过程已经保证第二子序列必然大于根结点
bool isLeft = isPosTree(a,p,r);
bool leftValued = true;//该过程验证第一子序列是否小于根结点
for (int i=p;i<r;i++)
{
if (a[i]>a[q])
{
leftValued=false;
break;
}
}
bool isRight = isPosTree(a,r+1,q-1);
return (isLeft&&isRight&&leftValued);
}
return true;
}