二分查找法及判断一个数组中是否有两个元素之和为指定值

来源:互联网 发布:苏州网络犯罪举报网站 编辑:程序博客网 时间:2024/05/16 11:57

请给出一个运行时间为O(nlgn)的算法,使之能在给定一个由n个整数构成的集合里快速判断是否存在两个元素,其和等于某一指定值key。

 

方法一:

 思路:

1.对数组进行归并排序或快速排序,运行时间为O(nlgn);

2.对已经排序的的数组进行遍历,并在遍历当前元素x时,在其后的序列里用binary search查找是否存在key-x,。binary search 运行时间为O(lgn),所以该步的的总运行时间为O(nlgn).

 

分析:该算法总的运行时间为O(nlgn)。

 

代码示例:

/*binary search: recursive edition  the input array is acsen-sorted array  the output is the index (starting from 0) of the array if found, or -1 if not found.  the total time is O(lgn)*/template<typename T>int BinarySearch(T arr[], int first,int last,const T key){if(first>last) return -1;if(first==last){if(key==arr[first])return first;elsereturn -1;}int mid=(first+last)/2;if(key==arr[mid]) return mid;else if(key<arr[mid]){return BinarySearch(arr,first,mid-1,key);}else{return BinarySearch(arr,mid+1,last,key);}}/*binary search: iterative editionthe input array is acsen-sorted arraythe output is the index (starting from 0) of the array if found, or -1 if not found.the total time is O(lgn)*/template<typename T>int BinarySearchItetive(T arr[],int first,int last,const T key){if(first>last) return -1;int mid=0;do {mid=(first+last)/2;if(key==arr[mid]){return mid;}else if(key<arr[mid]){last=mid-1;}else{first=mid+1;}} while (first<=last);return -1;}/*给出一个数组和一个关键字key,判断出数组中是否有两个元素,其和等于关键字key  要求运行时间为O(nlgn)*///first algorithmtemplate<typename T>bool CheckSum1(T arr[],int n,const T key){//first sort tht input array using merge sorting or quichsorting whose total time is O(nlgn)    MergeSort(arr,n);//searching using binary search whose total time is O(lgn)//therefore, the total time of searching is O(nlgn)for(int i=0;i<n-1;i++){if(BinarySearchItetive(arr,i+1,n-1,key-arr[i])>=0)return true;}return false;}

 

其中 函数MergeSort(...)见本博客另一篇文章 常见排序算法。

 

方法二:

思路:

1.用快速排序或并归排序对数组进行排序,并且如果有相同元素,则滤掉相同的元素,只保留一个;运行时间为O(nlgn)。

2.建立互补数组,其元素y=key-x,并且按升序排列;运行时间为O(n)。

3.合并两个数组,使用归并排序里的merge算法,运行时间为O(n)。

4.判断合并后的数组中是否有两个相邻且相等的元素对,运行时间为O(n)。

 

分析:

总运行时间为O(nlgn)。

 

代码:

//second algorithmtemplate<typename T>bool CheckSum2(T arr[],int n,const T key){//first sort tht input array using merge sorting or quichsorting whose total time is O(nlgn)MergeSort(arr,n);//filter same elements in the arrayT *a=new T[n];int m=0;for(int i=0;m<n&&i<n;i++){if(m==0){a[m++]=arr[i];}else if(arr[i]!=a[m-1]){a[m++]=arr[i];}}//construct another array storing key-x for each x in array aT *b=new T[m];for(int i=0;i<m;i++){b[i]=key-a[m-1-i];}//merge array a and array b    T *newarr=new T[2*m];for(int i=0;i<m;i++){newarr[i]=a[i];newarr[m+i]=b[i];}    delete [] a;delete [] b;Merge(newarr,0,m,2*m-1);    //searching by finding if there exists at least a pair of same elements in consective positons. for(int i=0;i<2*m-1;i++){if(newarr[i]==newarr[i+1]){delete [] newarr;return true;}}delete [] newarr;return false;}


 

其中 函数MergeSort(...)和Merge(...)见本博客另一篇文章 常见排序算法。


 

原创粉丝点击