Shirlies
宁静专注认真的程序媛~

题目:

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

链接:

http://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd?tpId=13&tqId=11176&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

思路:

首先在这里说一个问题:二叉搜索树没有表明左子树一定要比当前根节点要小吧?难道左子树比当前根节点大,右子树比当前根节点小就不是二叉搜索树了?

下面的代码是针对左子树比当前根节点小,右子树比当前根节点大的二叉搜索树的,如果需要具有普适性,下面的代码需要添加一个flag来判断搜索中的左右子树的大小关系。

1、选择当前序列中最后一个节点,记为rootNum

2、用rootNum在当前序列(不包括最后一个节点)二分查找,找到分割点div(前面的数字都小于rootNum,从分割点开始后面的数字都大于rootNum)

3、以div为界限,判断div前面的数是否都小于rootNum,div为起始,后面的数是否都大于rootNum,都满足的情况下,转4,否则,直接返回false

4、以div为end,遍历左子树,获取遍历结果,结果为true,转5,否则,返回false

5、以div为beg,遍历右子树,获取遍历结果,返回当前结果。

注意:二分查找时注意左子树或者右子树不存在的情况。

代码:

 1 class Solution {
 2 private:
 3     //二分查找当前序列中比findNum大,但是前面的一个数比findNum小的位置
 4     vector<int>::iterator binarySearch(
 5         vector<int>::iterator beg,
 6         vector<int>::iterator end,
 7         int findNum){
 8         if(end - beg == 1){
 9             if(*beg < findNum){
10                 return end;
11             }
12             return beg;
13         }
14         
15         vector<int>::iterator med = beg + ((end - beg) >> 1);
16         if(*med > findNum){
17             return binarySearch(beg,med,findNum);
18         }
19         
20         if(end - med == 1){
21             return end;
22         }
23         return binarySearch(med + 1,end,findNum);
24     }
25     
26     //判断序列是否都比compNum大或者小,gt为true表示要大,gt为false表示要小
27     bool compSeq(
28         vector<int>::iterator beg,
29         vector<int>::iterator end,
30         int compNum,
31         bool gt){
32         vector<int>::iterator iter;
33         for(iter = beg; iter < end; ++ iter){
34             if((*iter > compNum) != gt){
35                 return false;
36             }
37         }
38         
39         return true;
40     }
41     
42     //递归遍历二叉搜索树的后序遍历序列
43     bool visitSeq(vector<int>::iterator beg,vector<int>::iterator end){
44         if(beg == end || end - beg == 1){
45             return true;
46         }
47         
48         int rootNum = *(end - 1);
49         //找到分割点
50         vector<int>::iterator div = binarySearch(beg,end-1,rootNum);
51         //判断分割点的左右子树是否满足左子树小于当前数,右子树是否满足大于当前数
52         bool rightGt = compSeq(div,end-1,rootNum,true);
53         bool leftGt = compSeq(beg,div,rootNum,false);
54         //其中一个不满足就error了
55         if(!rightGt || !leftGt){
56             return false;
57         }
58         
59         //只有在右子树满足条件的情况下,才有必要去探索左子树
60         if(visitSeq(div,end-1)){
61             return visitSeq(beg,div);
62         }
63         
64         return false;
65     }
66 public:
67     bool VerifySquenceOfBST(vector<int> sequence) {
68         if(sequence.empty()){
69             return false;
70         }
71         
72         if(sequence.size() == 1){
73             return true;
74         }
75         
76         return visitSeq(sequence.begin(),sequence.end());
77     }
78 };

 

posted on 2016-09-02 11:30  Shirlies  阅读(340)  评论(0)    收藏  举报