问题:请给出一个运行时间为O(n lgn)的算法,使之能在给定一个由n个整数构成的集合S和另一个整数x时,
判断S中是否存在有两个其和等于x的元素。
题目思路:先将集合S用归并排序排好序,因为归并排序的运行时间为O(n lgn);设置low和
high两个标志指向集合的两端,将两个点相加与x比较,如果偏小,则将low向后移,如果偏小
则将high向前移。
1 #include<stdio.h> 2 #include<limits.h> 3 4 void Merge(int a[], int p, int q, int r); 5 void Merge_sort(int a[], int p, int r); 6 bool judge_sum(int a[], int p, int r, int x); 7 8 int main() 9 { 10 int n; 11 scanf("%d",&n); 12 13 int a[n + 1]; 14 int x; 15 16 for(int i = 1; i <= n; i++){ 17 scanf("%d",&a[i]); 18 } 19 scanf("%d",&x); 20 Merge_sort(a, 1, n); 21 if(judge_sum(a, 1, n, x)){ 22 printf("exist!"); 23 } 24 else{ 25 printf("not exist!"); 26 } 27 28 return 0; 29 } 30 31 bool judge_sum(int a[], int p, int r, int x){ //判断集合中是否有两个数相加等于x 32 int low = p; 33 int high = r; 34 35 while(low <= high){ 36 if(a[low] + a[high] < x) 37 low++; 38 else if(a[low] + a[high] > x) 39 high--; 40 else 41 return true; 42 } 43 44 return false; 45 } 46 47 void Merge(int a[], int p, int q, int r) 48 { 49 int n1 = q - p + 1; 50 int n2 = r - q; 51 int L[n1 + 1], R[n2 + 1]; 52 53 for(int i = 1; i <= n1; i++){ 54 L[i] = a[p + i - 1]; 55 } 56 for(int i = 1; i <= n2; i++){ 57 R[i] = a[q + i]; 58 } 59 60 L[n1 + 1] = INT_MAX; 61 R[n2 + 1] = INT_MAX; 62 63 int i = 1, j = 1; 64 for(int k = p; k <= r; k++){ 65 if(L[i] <= R[j]){ 66 a[k] = L[i]; 67 i++; 68 } 69 else{ 70 a[k] = R[j]; 71 j++; 72 } 73 } 74 } 75 76 void Merge_sort(int a[], int p, int r) 77 { 78 if(p < r){ 79 int q = (p + r) / 2; 80 Merge_sort(a, p, q); 81 Merge_sort(a, q+1, r); 82 Merge(a, p, q, r); 83 } 84 }