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

请给出一个运行时间为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(...)见本博客另一篇文章 常见排序算法。


 

你可能感兴趣的:(算法,delete,search,input,merge,sorting)