剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列

剑指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 }

 

你可能感兴趣的:(遍历)