目录
题目描述
思路
说实话,我第一眼看到这个题目,一点思路都没有,除了知道二叉树后序遍历遵循"左右根"的遍历方式以外其他的什么都不知道,两眼一抹黑....
后来看了题解又摸索着自己写,写来写去,都有问题,emmm,看别人写的十分简洁,自己写的一堆废话.实在是让我汗颜........
后来不得已去看了K神的题解.
正文
思想就是分治递归,我们寻找第一个大于最后一个元素的节点,保存这个位置的index,然后移动当前下标直到到达right,凭借postorder[right]将数组分为两部分,[left,index-1],[index,right-1] (注:这里的右子树一定是index,而不是index+1).再对这两部分进行递归判断,结果相与&&,最后还要判断游标是否到达right,因为index右边的元素(除了下标为right的元素)应该都是大于下标为right的元素,因为二叉搜索树的性质. 一直递归下去,知道left>=right,直接返回true
分治
大问题换成小问题, 我们求一个长序列,转化为求两个小区间序列是否满足条件.这和递归的大势化小的思想是相似的,
代码
class Solution {
public:
bool judge(vector<int>& postorder, int left, int right) //左闭右闭区间
{
int temp=left;
int index;
if (left >= right) return true;
while (postorder[temp] < postorder[right]) ++temp;
index = temp;
while (postorder[temp] > postorder[right]) ++temp;
return temp==right&&judge(postorder, left, index - 1) && judge(postorder, index, right-1);
}
bool verifyPostorder(vector<int>& postorder) {
return judge(postorder,0, postorder.size() - 1);
}
};