剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列
2013-11-23 03:16
题目描述:

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

输入:

每个测试案例包括2行:

第一行为1个整数n(1<=n<=10000),表示数组的长度。

第二行包含n个整数,表示这个数组,数组中的数的范围是[0,100000000]。

输出:

对应每个测试案例,如果输入数组是某二叉搜索树的后序遍历的结果输出Yes,否则输出No。

样例输入:
7
5 7 6 9 11 10 8
4
7 4 6 5
样例输出:
Yes
No
题意分析:
  题目要求给定一个数组,判断此数组能不能是一颗BST的后序遍历。对于后序遍历,最后一个元素对应根节点,前一段元素小于根节点,后一段元素大于根节点。
  对于数组a[n],如果存在1<=k<=n,使得a[1]~a[k - 1]均小于a[n],a[k]~a[n - 1]均大于a[n],则可以划分出两个子树,两个子树可以为空。
  按照这种划分标准递归往下检查所有子树,全部符合的话,说明能够造出一个二叉搜索树。否则不符合二叉搜索树的结构。
  所有节点遍历一次,有O(n)时间开销,但因为找出划分左右子树的节点a[k]需要O(n)的开销,所以实际是O(nlog n),推导如下:
    T(n) = 2 * T(n / 2) + O(1) + O(n)
    T(n) = 2 * T(n / 2) + O(n)
    T(n) = 4 * T(n / 4) + 2 * (O(n / 2)) + O(n)
    T(n) = 4 * T(n / 4) + 2 * O(n)
    T(n) = 2 ^ log(n) * T(1) + log(n) * O(n)
    T(n) = O(n) + O(n * log(n))
    T(n) = O(n * log(n))
  空间复杂度O(1),不需要额外数组。
 1 // 652939    zhuli19901106    1367    Accepted    点击此处查看所有case的执行结果    1020KB    1192B    10MS
 2 // 201311172259
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 bool check_postorder(const int a[], int left, int right)
 7 {
 8     if(a == NULL || left < 0 || right < 0 || left > right){
 9         return false;
10     }
11     
12     if(left == right){
13         return true;
14     }
15     
16     int i;
17     
18     i = left;
19     while(i <= right - 1 && a[i] < a[right]){
20         ++i;
21     }
22     if(i == right){
23         // right substree is empty
24         return check_postorder(a, left, right - 1);
25     }else if(i == left){
26         // left substree is empty
27         for(; i <= right - 1; ++i){
28             if(a[i] < a[right]){
29                 return false;
30             }
31         }
32         return check_postorder(a, left, right - 1);
33     }else{
34         int pos = i;
35         for(; i <= right - 1; ++i){
36             if(a[i] < a[right]){
37                 return false;
38             }
39         }
40         return check_postorder(a, left, pos - 1) && check_postorder(a, pos, right - 1);
41     }
42 }
43 
44 int main()
45 {
46     const int MAXN = 10005;
47     int a[MAXN];
48     int n, i;
49     
50     while(scanf("%d", &n) == 1){
51         for(i = 0; i < n; ++i){
52             scanf("%d", &a[i]);
53         }
54         if(check_postorder(a, 0, n - 1)){
55             printf("Yes\n");
56         }else{
57             printf("No\n");
58         }
59     }
60     
61     return 0;
62 }

 

 posted on 2013-11-23 03:40  zhuli19901106  阅读(265)  评论(0编辑  收藏  举报