题目:输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。如果有多对数字的和等于输入的数字,输出任意一对即可。
例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。
分析:1.直接穷举。从数组中任意选取两个数,判定它们的和是否为输入的那个数字。此方法与数组有序或者无序无关,时间复杂度为O(n)。
View Code
1 #include <iostream.h> 2 3 bool Find2Num(int *data,int n,int sum,int &num1,int &num2) 4 { 5 if (NULL==data || n<=1) 6 { 7 return false; 8 } 9 10 for (int i=0;i<n;i++) 11 { 12 for (int j=i+1;j<n;j++) 13 { 14 if (data[i]+data[j]==sum) 15 { 16 num1=data[i]; 17 num2=data[j]; 18 return true; 19 } 20 else 21 { 22 continue; 23 } 24 } 25 } 26 27 return false; 28 } 29 30 void main() 31 { 32 int data[6]={1,2,4,7,15,11}; 33 int sum=15; 34 int num1,num2; 35 36 if (Find2Num(data,6,sum,num1,num2)) 37 { 38 cout<<num1<<" "<<num2<<endl; 39 } 40 else 41 { 42 cout<<"doesn't exsit!"<<endl; 43 } 44 45 }
2.对每个a[i],然后查找sum-a[i]是否也在原始序列中,在查找的过程中采用二分查找,然而二分查找需序列是有序的,所以需要对数组进行排序。排序所需的时间为O(N*logN)。对N个a[i],每个都需要花费O(logN)的时间去查找,故查找的过程所需时间为O(N*logN).总的花费时间为O(N*logN+N*logN)=O(N*logN)。
View Code
1 #include <iostream.h> 2 #include <algorithm> 3 using namespace std; 4 5 int BinarySearch(int *data,int n,int num) 6 { 7 int low=0; 8 int high=n-1; 9 int middle,position; 10 while(low<=high) 11 { 12 middle=(low+high)/2; 13 if (data[middle]<num) 14 { 15 low=middle+1; 16 } 17 else if (data[middle]>num) 18 { 19 high=middle-1; 20 } 21 else 22 { 23 position=middle; 24 25 return position; 26 } 27 } 28 29 30 return -1; 31 } 32 33 bool FindSum2(int *data,int n,int sum,int &num1,int &num2) 34 { 35 if (NULL==data || n<=1) 36 { 37 return false; 38 } 39 40 int findnum,index; 41 42 for (int i=0;i<n;i++) 43 { 44 findnum=sum-data[i]; 45 index=BinarySearch(data,n,findnum); 46 if (index!=-1 && index!=i) 47 { 48 num1=data[i]; 49 num2=data[index]; 50 return true; 51 } 52 else 53 { 54 continue; 55 } 56 } 57 58 return false; 59 60 } 61 62 void main() 63 { 64 int data[6]={1,2,4,7,15,11}; 65 int sum=15; 66 int num1,num2; 67 sort(data,data+6); 68 69 if (FindSum2(data,6,sum,num1,num2)) 70 { 71 cout<<num1<<" "<<num2<<endl; 72 } 73 else 74 { 75 cout<<"doesn't exsit!"<<endl; 76 } 77 78 }
3.如果数组是无序的,则首先采用快速排序算法排好序,所需时间为O(N*logN)。然后用两个指针i,j,分别指向数组的首端和尾端,令i=0,j=n-1;然后i++,j--;逐次判断a[i]+a[j]?=sum。如果某时刻a[i]+a[j]>sum,则j--,i不动;如果某时刻a[i]+a[j]<sum,则i++,j不动。终止条件是i>=j。此遍历过程的时间复杂度为O(N),所以此方法总的时间复杂度为O(N*logN+N)=O(N*logN).倘若数组本身是有序的,则此方法的时间复杂度降为O(N)。
实现一
1 #include <iostream.h> 2 #include <algorithm> 3 using namespace std; 4 5 bool Find2Num(int *data,int n,int sum,int &num1,int &num2) 6 { 7 if (NULL==data || n<=1) 8 { 9 return false; 10 } 11 12 int *begin=data; 13 int *last=data+n; 14 sort(begin,last);//排序 15 16 int low=0,high=n-1; 17 while(low<high) 18 { 19 if (data[low]+data[high]<sum) 20 { 21 low++; 22 } 23 else if (data[low]+data[high]>sum) 24 { 25 high--; 26 } 27 else 28 { 29 num1=data[low]; 30 num2=data[high]; 31 return true; 32 } 33 } 34 35 return false; 36 37 } 38 39 void main() 40 { 41 int data[6]={1,2,4,7,15,11}; 42 int num1,num2; 43 int sum=15; 44 bool flag=Find2Num(data,6,sum,num1,num2); 45 if (flag) 46 { 47 cout<<"exist two numers:"<<num1<<" and "<<num2<<" which theirs sum equal to "<<sum<<endl; 48 } 49 else 50 { 51 cout<<"doesn't exist!"<<endl; 52 } 53 }
实现二
1 #include <iostream.h> 2 #include <algorithm> 3 #include <utility> 4 using namespace std; 5 6 7 pair<int,int> FindSum(int *data,int n,int sum) 8 { 9 if (NULL==data || n<=1) 10 { 11 return make_pair(-1,-1); 12 } 13 14 sort(data,data+n);//排序 15 16 int *begin=data; 17 int *last=data+n-1; 18 19 while(begin<last) 20 { 21 if (*begin+*last<sum) 22 { 23 begin++; 24 } 25 else if (*begin+*last>sum) 26 { 27 last--; 28 } 29 else 30 { 31 return make_pair(*begin,*last); 32 } 33 } 34 35 return make_pair(-2,-2); 36 } 37 38 void main() 39 { 40 int data[6]={1,2,4,7,15,11}; 41 int sum=15; 42 pair<int,int> p; 43 p=FindSum(data,6,sum); 44 cout<<p.first<<" "<<p.second<<endl; 45 }