题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
概念
1、二叉搜索树:二叉搜索树(英语:Binary Search Tree),也称二叉查找树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 任意节点,如果左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
- 任意节点,如果右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点。
2、后序遍历:后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。
方法一
1、由于是后序遍历,遍历顺序为左右根,那么序列的最后一个节点必为根节点;
2、根据二叉搜索树特点:左子树小于根节点,右子树大于根节点,可以很容易根据元素与根节点值大小的比较,找出根节点的左子树及右子树。然后判断左子树节点的值是否都小于根节点的值,右子树节点的值是否都大于根节点的值,判断左右子树对应的序列是否是二叉搜索树的后序遍历的结果。很明显,可以用递归的思路去解决问题 。
代码
class Solution { public: bool VerifySquenceOfBST(vector<int> sequence) { if( sequence.empty() ) return false; return help( sequence, 0, sequence.size()-1 ); } bool help( vector<int> input, int first, int last ) { if( last-first <= 1 ) return true; int small_last = last-1; while( input[small_last] > input[last] )//找左右子树分界点 small_last--; for( int i=first;i<=small_last;i++ )//保证左子树部分都小于root if( input[i] > input[last] ) return false; return help(input, first, small_last) && help(input, small_last+1, last-1 ); } };
方法二
由于后序遍历以及二叉搜索树的特点,对于序列中每一个节点来说,位于该节点之前的节点,从左到右看,应该是连续的小于该节点值,然后是连续的大于该节点的值,如果出现交叉现象,说明该序列不是二叉搜索树的后序遍历的结果。描述不太清楚,直接看代码就好。
代码
class Solution { public: bool VerifySquenceOfBST(vector<int> sequence) { int length=sequence.size(); if(length==0) return false; int i=0; while(--length) { while(sequence[i++]<sequence[length]); while(sequence[i++]>sequence[length]); if(i<length) return false; i=0; } return true; } };