请给出一个运行时间为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; else return -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 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 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 algorithm template<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 algorithm template<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 array T *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 a T *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(...)见本博客另一篇文章 常见排序算法。