算法导论习题2.3-7

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

解答:

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

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

  1. #include<iostream>
  2. constintMAXINT=0xFFFF-1;
  3. voidMerge(intA[],intstart,intmid,intend)
  4. {
  5. intlen1=mid-start+1+1;//加一个位置用于保存哨兵
  6. intlen2=end-mid+1;//加一个位置用于保存哨兵
  7. int*L=newint[len1];
  8. int*R=newint[len2];
  9. for(inti=0;i<len1-1;i++)
  10. L[i]=A[start+i];
  11. L[len1-1]=MAXINT;
  12. for(intj=0;j<len2-1;j++)
  13. R[j]=A[mid+j+1];
  14. R[len2-1]=MAXINT;
  15. i=0;j=0;
  16. for(intk=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. voidMergeSort(intA[],intstart,intend)
  31. {
  32. if(start<end)
  33. {
  34. intmid=(end+start)/2;
  35. MergeSort(A,start,mid);
  36. MergeSort(A,mid+1,end);
  37. Merge(A,start,mid,end);
  38. }
  39. }
  40. voidFind(intA[],intn,intx)
  41. {
  42. intneedValue;
  43. intleft,right,leftPosition,middle;
  44. leftPosition=0;
  45. intcount=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. inttemp;
  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<<"thetotalnumberis"<<count<<std::endl;
  82. }
  83. intmain(void)
  84. {
  85. int*a;
  86. intx;
  87. intn;
  88. std::cout<<"Pleaseinputthetwonumber'ssum:"<<std::endl;
  89. std::cin>>x;
  90. std::cout<<"Pleaseinputthearray'ssize:/n";
  91. std::cin>>n;
  92. a=newint[n];
  93. std::cout<<"Pleaseinputthearray'value:"<<std::endl;
  94. for(inti=0;i<n;i++)
  95. std::cin>>a[i];
  96. MergeSort(a,0,n-1);
  97. std::cout<<"Thesortednumberseries:";
  98. for(i=0;i<n;i++)
  99. std::cout<<""<<a[i];
  100. std::cout<<std::endl<<"theresult:/n";
  101. Find(a,n,x);
  102. return0;
  103. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值