题目:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
解题思路:
1. 二叉搜索树:左子树永远比右子树小
2. 后序遍历:最后访问根节点
由上述两点可知:后序遍历序列的最后是根节点,可以将前面的部分分为比它小的左子树和比它大的右子树。
1、递归:
这道题很显然我们可以用递归的方法来做:只要我们判断当前序列的最后节点,可以将前面序列可以完全分解为左子树序列和右子树序列,并且这两个序列也满足这样的条件,那个这个序列就是正确的。
1)找到序列的最后一个元素a
2)判断a能否将序列完全分解成左子树序列和右子树序列
i = 0;
while(seq[i]<a)压入左子树;i++;
while(seq[i]>a)压入右子树;i++;
if(左子树+右子树=序列的长度 && 左子树满足条件 && 右子树满足条件)return true;
return false;
代码:
这里我采用的方法是用两个vector<int>数组来存储左子树和右子树,大家也可以采用记录左右子树开始和结束的索引的方法,将这两个索引值作为函数参数传入,这样可以节省存储空间。
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
if(sequence.size()==0)return false;
return isSquenceOfBST(sequence);
}
bool isSquenceOfBST(vector<int> sequence){
if(sequence.size()==1 || sequence.size()==0)return true;
int a = sequence[sequence.size()-1];
int i=0;
vector<int> left;
vector<int> right;
while(sequence[i]<a){
left.push_back(sequence[i]);
++i;
}
while(sequence[i]>a){
right.push_back(sequence[i]);
++i;
}
if(left.size()+right.size() == sequence.size()-1)
if(isSquenceOfBST(left) && isSquenceOfBST(right))
return true;
return false;
}
};
2、非递归:
非递归其实也使用了类似的思想。
每个序列的最后一个值一定是可以把前面的序列划分为左右子树的。
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
int size = sequence.size();
if(size==0)return false;
while(size--){
int i=0;
while(sequence[size]>sequence[i]){i++;}
while(sequence[size]<sequence[i]){i++;}
if(i!=size)return false;
}
return true;
}
};