题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
思路: 二叉树的后序遍历也就是先访问左子树,再访问右子树,最后访问根节点,所以不难发现,所给的数组最后一个元素一定是二叉搜索树的根节点,而如果数组是二叉搜索树的后续遍历的话,就一定会根据数值划分两部分,左边是根节点的左子树,剩下的部分则是根节点的右子树。左子树的数值均小于根节点,右子树的数值均大于根节点。
例如{5,7,6,9,11,10,8},8是二叉搜索树的根节点,{5,7,6}是左子树,{9,11,10}是右子树。再递归判断。
6是根节点,5是左子树,7是右子树,由于只剩一个元素了,判断中止,同理{9,11,10}也是如此。
但如果不是后序遍历的序列,如{7,4,6,5}
5是根节点,7,4,6三个元素没有办法划分出左右子树,因为二叉搜索树的特性我们知道,左子树所有元素的值都小于根节点,右子树的值均大于根节点,无论是{7},{4,6}还是{7,4},{6}均不符合二叉搜索树的性质,在编程实现的过程中,我们可以遍历数组,当出现第一个大于根节点的元素时,便认为之前的所有元素时这个根节点的左子树,而排除最后一个元素剩下的所有元素便是右子树,查看右子树中的元素如果有小于根节点的元素,便可以直接判断不是二叉搜索树的后续遍历,如果没有就递归执行下去。
C++
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
if (sequence.size() <= 0)
return false;
int len = sequence.size();
//获取后续遍历的最后一个数,是二叉搜索树的最后一个元素,即根节点
int root = sequence[len - 1];
vector<int>left, right; //左右子树
int i = 0;
for (; i < len - 1; i++)
{
if (sequence[i] > root)
break;
left.push_back(sequence[i]); //比根节点小的放左子树
}
int j = i;
for (; j < len - 1; j++)
{
if (sequence[j] < root)
return false;
right.push_back(sequence[j]); //比根节点大的放右子树
}
bool aleft = true;
if (i > 0)
aleft = VerifySquenceOfBST(left); //递归判断
bool aright = true;
if (i < len - 1)
aright = VerifySquenceOfBST(right);
return (aleft && aright);
}
};
参考
https://www.cnblogs.com/silentteller/p/11924310.html