zoukankan      html  css  js  c++  java
  • 算法导论2.37习题解答(合并排序算法及二分查找)

    CLRS 2.3-7 :请给出一个运行时间为O(nlgn)的算法,是之能在一个由n个整数构成的集合S和另一个整数x时,判断出S中是否存在有两个其和等于x的元素。

    算法思想:
    1.先运用合并排序进行排序 O(nlgn),
    2.然后运用二分查找法寻找y,y = x - a[i];

    代码如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void sort(int*&a, int p, int q, int r)
     5 {
     6   int* left =new int[q - p +1];
     7   int* right =new int[r - q];
     8   for(int i =0; i < q - p +1; i++)
     9     left[i] = a[p + i];
    10   for(int i =0; i < r - q; i++)
    11     right[i] = a[q + i +1];
    12 
    13   int m =0;
    14   int n =0;
    15   //书上在这里用的是在数组末尾添加一个数,即"哨兵牌"
    16   //作者同时让我们不用"哨兵牌"来实现
    17   //我在这里采取的是,如果到达一个数组的末尾,
    18   //那么另外一个数组的剩余元素就不用比较了,然后可以完全复制到a,见27行.
    19   //时间复杂度未变,因为27行的循环紧跟20行的循环而已,你可以看到结束条件都是i<=r,j<=r,然后break
    20   for(int i = p; i <= r; i++) {
    21     if(left[m] <= right[n]) {
    22       a[i] = left[m];
    23       if(m++== q-p) {
    24         for(int j = i +1; j <= r; j++)
    25           a[j] = right[n++];
    26         break;
    27       }
    28     } else {
    29       a[i] = right[n];
    30       if(n++== r-q-1) {
    31     for(int j = i +1; j <= r; j++)
    32       a[j] = left[m++];
    33     break;
    34       }
    35     }
    36   }
    37   
    38   delete[] left;
    39   delete[] right;
    40 }
    41 void merge(int*&a, int m, int n)
    42 {
    43   if(m < n) {
    44     int q = (m + n)/2;
    45     merge(a, m, q);
    46     merge(a, q+1, n);
    47     sort(a, m, q, n);
    48   }
    49 }
    50 
    51 //二分查找
    52 bool binary_search(int* a, int n, int goal)
    53 {
    54   int middle = (n -1)/2;
    55   int high = n -1;
    56   int low =0;
    57   while(low <= high) {
    58     if(a[middle] == goal)
    59       return true;
    60     else if(a[middle] >= goal)
    61       high = middle -1;
    62     else
    63       low = middle +1;
    64     middle = (low + high)/2;
    65   }
    66   return false;
    67 }
    68 
    69 int main()
    70 {
    71   const int LEN =1000000;
    72   //用max来代表最大数,你可以任意选取
    73   int max =100000000;
    74   int* a =new int[LEN];
    75   for(int i =0; i < LEN; i++)
    76     a[i] = LEN - i;
    77   merge(a, 0, LEN -1);
    78 
    79   int x;
    80   cin>>x;
    81   if(!(x%2)) {
    82     for(int i =0; i < LEN; i++)
    83       if(a[i] == x/2) {
    84         a[i] = max;
    85         break;
    86       }
    87   }
    88   
    89   for(int i =0; i < LEN; i++)
    90     if(binary_search(a, LEN, x - a[i])) {
    91       cout<<"YES"<<endl;
    92       break;
    93     }
    94   
    95   delete a;
    96   return 0;
    97 }
    ---
    可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
  • 相关阅读:
    KMP
    C. Three Base Stations
    Calculation 2 [HUD 3501]
    组合数 com(n,r)
    Keep Deleting [zoj 3643]
    LightSwitch V1.0 正式发布,配套控件收集 !
    微软 Lightswitch 学习研讨 QQ群:97010590
    IIS 7开发与管理完全参考手册
    电影 下载 地址收集
    2011年A股中报十大筹码集中王 (收藏)
  • 原文地址:https://www.cnblogs.com/null00/p/2065085.html
Copyright © 2011-2022 走看看