zoukankan      html  css  js  c++  java
  • 剑指Offer

    剑指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
    ");
    56         }else{
    57             printf("No
    ");
    58         }
    59     }
    60     
    61     return 0;
    62 }
  • 相关阅读:
    C++中的头文件和源文件
    串口VMIN VTIME 详解
    lms111,rplidar 方向和起始角
    Nginx访问限制配置
    Nginx请求限制配置
    Nginx模块详解
    Nginx默认配置语法
    Nginx编译参数详解
    Nginx安装目录详解
    Nginx的快速安装
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3438577.html
Copyright © 2011-2022 走看看