20,判断是不是二叉搜索树的后序遍历《剑指offer》
题目:
给定一个序列,判断是不是二叉搜索树的后序遍历
思路:
递归版:
一个正确的后序遍历可以分为三段来看: 1:最后一个值是根节点 2:左子树节点(都比根节点值小) 3:右子树节点(都比根节点大)
且满足左子树个数加右子树个数等于N-1;(N为后序遍历的节点总个数)
左子树和右子树又可以进行同样的操作,,,perfect的递归定义哈
然后判断出口:
1,正确的出口,子树只有一个元素或者零个元素(这零就是为什么要多写一个函数的原因了。。)
2,错误的出口,左子树加上右子树的个数不等于N-1
ps:这个递归版本加了辅助空间,其实可以优化下,传递索引的值就好,也就是左边界left,右边界right;当然出口的条件也要相应的改变
非递归版本:
自己没有想到一个比较好的方案,只能看别人写的代码学习学习了哈:
大体的循环顺序是:根-->右子树或者左子树
首先访问根节点,然后进行左子树,右子树的划分,然后判断长度
然后访问第N-1个,同样以他为根节点进行划分两种情况:
1,要么是左子树最大的节点
2,要么是右子树最大的节点
第一种情况就和之前一样;
第二种情况下,因为正确情况下左子树都比这个根节点的值小所以,没有丝毫影响最后的长度判断(相当于同时加left长度)
代码:
递归版:
class Solution { public: bool VerifySquenceOfBST(vector<int> sequence) { if(sequence.size()==0) return false; return verify(sequence); } bool verify(vector<int> sequence){ if(sequence.size()==1||sequence.size()==0) return true; vector<int> left; vector<int> right; int n=sequence.size()-1; int i=0; int root=sequence[n]; while(sequence[i]<root) left.push_back(sequence[i++]); while(sequence[i]>root) right.push_back(sequence[i++]); if(i<n) return false; return verify(left)&&verify(right); } };
非递归:
class Solution { public: bool VerifySquenceOfBST(vector<int> sequence) { int size=sequence.size(),i=0; if(size==0) return false; while(--size){ while(sequence[i++]<sequence[size]); while(sequence[i++]>sequence[size]); if(i<size) return false; i=0; } return true; } };