算法导论习题2.3-7

来源:互联网 发布:windows server pack 编辑:程序博客网 时间:2024/05/01 13:07

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

解答:

首先对S进行排序,使用合并算法进行排序,排序算法的时间复杂度为nlogn。

然后对排序的S从左到右(即从大到小)进行算法,首先锁定一个数i,这个数小于x的一半,然后从这个数的右边开始查找x-i,使用2分法查找,算法的时间复杂度小于nlogn,所以总的时间复杂度还是nlogn。

  1. #include <iostream> 
  2. const int MAXINT=0xFFFF-1;
  3. void Merge(int A[], int start, int mid, int end)
  4. {
  5.     int len1 = mid-start+1+1;//加一个位置用于保存哨兵 
  6.     int len2 = end-mid+1;//加一个位置用于保存哨兵 
  7.     int *L =new int[len1];
  8.     int *R =new int[len2];
  9.     for(int i=0;i<len1-1;i++)
  10.         L[i]=A[start+i];
  11.     L[len1-1]=MAXINT;
  12.     for(int j=0;j<len2-1;j++)
  13.         R[j]=A[mid+j+1];
  14.     R[len2-1]=MAXINT;
  15.     i=0;j=0;
  16.     for(int k=start;k<=end;k++)
  17.     {
  18.         if(L[i]<=R[j])
  19.         {
  20.             A[k]=L[i];
  21.             i++;
  22.         }
  23.         else
  24.         {
  25.             A[k]=R[j];
  26.             j++;
  27.         }
  28.     }
  29. }
  30. void MergeSort(int A[], int start, int end)
  31. {
  32.     if(start<end)
  33.     {
  34.         int mid = (end +start)/2;
  35.         MergeSort(A,start,mid);
  36.         MergeSort(A,mid+1,end);
  37.         Merge(A,start,mid,end);
  38.     }
  39. }
  40. void Find(int A[], int n, int x)
  41. {
  42.     int needValue;
  43.     int left,right,leftPosition,middle;
  44.     leftPosition=0;
  45.     int count=0;
  46.     while(A[leftPosition]<=x/2)
  47.     {
  48.         needValue = x - A[leftPosition];
  49.         left=leftPosition+1;
  50.         right=n-1;
  51.         while(left<=right)
  52.         {
  53.             middle=(left+right)/2;
  54.             if(A[middle]>needValue)
  55.                 right=middle-1;
  56.             else
  57.                 if(A[middle]<needValue)
  58.                     left=middle+1;
  59.                 else
  60.                 {
  61.                     std::cout<<"the "<<++count<<" : ";
  62.                     std::cout<<x<<"="<<A[leftPosition]<<"+"<<needValue<<std::endl;
  63.                     int temp;
  64.                     temp=middle;
  65.                     while(A[--temp]==needValue)
  66.                     {
  67.                         std::cout<<"the "<<++count<<" : ";
  68.                         std::cout<<x<<"="<<A[leftPosition]<<"+"<<needValue<<std::endl;
  69.                     }
  70.                     temp=middle;
  71.                     while(A[++temp]==needValue)
  72.                     {
  73.                         std::cout<<"the "<<count++<<" : ";
  74.                         std::cout<<x<<"="<<A[leftPosition]<<"+"<<needValue<<std::endl;
  75.                     }
  76.                     break;
  77.                 }
  78.         }
  79.         leftPosition++;
  80.     }
  81.     std::cout<<"the total number is "<<count<<std::endl;
  82. }
  83. int main(void)
  84. {
  85.     int *a;
  86.     int x; 
  87.     int n;
  88.     std::cout<<"Please input the two number's sum: "<<std::endl;
  89.     std::cin>>x;
  90.     std::cout<<"Please input the array's size: /n";
  91.     std::cin>>n;
  92.     a=new int[n];
  93.     std::cout<<"Please input the array' value: "<<std::endl;
  94.     for(int i=0;i<n;i++)
  95.         std::cin>>a[i];
  96.     MergeSort(a,0,n-1);
  97.     std::cout<<"The sorted number series: ";
  98.     for(i=0;i<n;i++)
  99.         std::cout<<" "<<a[i];
  100.     std::cout<<std::endl<<"the result:/n";
  101.     Find(a,n,x);
  102.     return 0;
  103. }