• 从头看算法导论 习题2.3-7 深入分析


    题目:请给出一个时间复杂度为nlogn的算法,使之能够在给定一个由n个整数的构成的整合S和另一个整数x时,判断出S中是否存在有两个其和等于x的元素。

    算法思想:
    1.先运用合并排序进行排序 O(nlgn),
    2.然后运用二分查找法寻找y,y = x - a[i],算法的时间复杂度小于nlogn,所以总的时间复杂度还是nlogn。

    批注:该思想,不是最好的(从简洁、时间复杂度上得到结论),不喜勿喷。

    代码如下:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define MAX 99999
     4 #define MAXINT 0xFFFF-1
     5 int num[MAX];
     6 
     7 void UniteSort(int *a,int start,int mid,int end)
     8 {
     9     int left_len=mid-start+1+1,right_len = end-mid+1;//加一个位置用于保存哨兵
    10     int *left = (int*)malloc(sizeof(int)*left_len);//加一个位置用于保存哨兵
    11     int *right = (int*)malloc(sizeof(int)*right_len);
    12     
    13     for(int i =0; i < left_len-1; i++)
    14         left[i] = a[start + i];
    15     left[left_len-1]=MAXINT;
    16     for(int i =0; i < right_len-1; i++)
    17         right[i] = a[mid + i +1];
    18     right[right_len-1]=MAXINT;
    19     
    20     int m=0,n=0;    
    21     for(int i=start;i<=end    ;i++)
    22     {
    23         if(left[m]<=right[n])
    24         {
    25             a[i]=left[m];
    26             m++;
    27         }
    28         else
    29         {
    30             a[i]=right[n];
    31             n++;
    32         }
    33     }
    34     free(left);
    35     free(right);
    36 }
    37 
    38 void merge(int *a,int start,int end)
    39 {
    40     if(start<end)
    41     {
    42         int mid = (start+end)/2;
    43         merge(a,start,mid);
    44         merge(a,mid+1,end);
    45         UniteSort(a,start,mid,end);
    46     }
    47 }
    48 
    49 //二分查找
    50 bool binary_search(int* a, int n, int goal)
    51 {
    52   int middle = (n -1)/2;
    53   int high = n -1;
    54   int low =0;
    55   while(low <= high) {
    56     if(a[middle] == goal)
    57       return true;
    58     else if(a[middle] >= goal)
    59       high = middle -1;
    60     else
    61       low = middle +1;
    62     middle = (low + high)/2;
    63   }
    64   return false;
    65 }
    66 
    67 int main()
    68 {
    69     int x;
    70       scanf("%d",&x);
    71     // init
    72     for(int i=0;i<MAX;i++)
    73         num[i]=MAX-i;
    74         
    75       merge(num, 0, MAX -1);
    76     
    77      for(int i =0; i < MAX; i++)
    78         if(binary_search(num, MAX, x - num[i])) 
    79         {
    80               printf("YES
    ");
    81               break;
    82         }
    83     
    84     return 0;
    85 }

    刚才提到,还有更好的代码,这里不得不介绍拉。

    首先归并算法,不是最好的?比归并排序还要好的是“快速排序”。可能有人要问为什么?(它们的时间复杂度,平均都是nlgn,快排最坏的情况是n的平方)分析如下:

    快速排序算法和合并排序保持在相同的数量级下,但面对越大基数的无序数列时,快速排序的用时更短.——结论选自:快速排序与合并排序的分析与比较 (百度文库)

    为什么造成这样的情况呢?因为快速排序是原地排序,归并是递归调用,没在原地操作(这里有人不要说,快排不稳定的废话了)。如上面的代码,归并排序中,临时开闭了新的数组空间而照成时间的流失(归并需要额外空间 )——参考《深入理解计算机系统》局部性原理。

    故,这里排序换成快速排序,在基数大的情况下,快速排序最快拉。

     

    如上又提到“简洁”,在STL中,有现成的快速排序函数qsort、二分查找函数binary_search.我们得站在巨人的肩膀上····

    在同样的条件下,sort()(默认从小到大排序),也是不错的选择。

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <algorithm>
     4 
     5 #define MAX 99999
     6 #define MAXINT 0xFFFF-1
     7 int num[MAX];
     8 
     9 int comp(const void*a,const void*b){return*(int*)a-*(int*)b;}
    10 int main()
    11 {
    12     int x;
    13       scanf("%d",&x);
    14     // init
    15     for(int i=0;i<MAX;i++)
    16         num[i]=MAX-i;    
    17         
    18 //    qsort(num,MAX,sizeof(int),comp);
    19     std::sort(num,num+MAX);
    20      for(int i =0; i < MAX; i++)
    21          //binary_search返回值: 如果数组中找到target, 返回其下标;否则返回 -1
    22         if(std::binary_search(num, num+MAX, x - num[i])!=-1) 
    23         {
    24               printf("YES
    ");
    25               break;
    26         }
    27     
    28     return 0;
    29 }
    作者:orange1438
    出处:http://www.cnblogs.com/orange1438/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    iis7 下配置 ASP.NET MVC 项目遇到的问题 (WIN7 64位 旗舰版 第一次配置站点)
    C# .NET 使用 NPOI 读取 .xlsx 格式 Excel
    C# .NET 使用 NPOI 生成 .xlsx 格式 Excel
    SQL和T-SQL之间的区别
    .net core的服务器模式和工作站模式
    Windows Mysql8 设置大小写敏感
    每个国家对应的语言Locale和国家代码对照表(转)
    IL指令集
    使用 nvm 管理不同版本的 node 与 npm
    SSIS 包部署 Package Store 后,在 IS 中可以执行,AGENT 执行却报错
  • 原文地址:https://www.cnblogs.com/orange1438/p/4161658.html
Copyright © 2020-2023  润新知