描述一个运行时间为Θ(nlgn)的算法,给定n个整数的集合S和另一个整数x,该算法能确定S中是否存在两个其和刚好为x的元素

算法思路:
首先对S[1...n]进行非降序排序,然后设置两个指向标i=1,j=n,执行下面的操作:
S[i] + S[j] = X,  返回true
           < X,     i = i+1
        > X,     j = j-1

           如果 i>j 返回false


#include <iostream>
#include <ctime>
#include <limits>

using namespace std;

void merge(int *a,int low,int mid,int high)//哨兵法 归并排序
{
	int Ln=mid-low+1;
	int Rn=high-mid;

	int *La=new int[Ln+1];
	int *Ra=new int[Rn+1];

	for(int i=0;i<Ln;++i){
		La[i]=a[low+i];
	}
	for(int j=0;j<Rn;++j){
		Ra[j]=a[mid+j+1];
	}
	La[Ln]=numeric_limits<int>::max();
	Ra[Rn]=numeric_limits<int>::max();

	int m=0,n=0;
	for(int k=low;k<=high;++k){
		if(La[m]<=Ra[n]){
			a[k]=La[m];
			++m;
		}else{
			a[k]=Ra[n];
			++n;
		}
	}	
}

void merge_sort(int * a,int low,int high)//O(n*lgn)
{
	if(low<high){
		int mid=(low+high)>>1;
		merge_sort(a,low,mid);
		merge_sort(a,mid+1,high);
		merge(a,low,mid,high);
	}
}

bool sum_to_x(int *a,int low,int high,int x)//求序列S中是否存在两个数之和为X,O(n)
{
	int i=low,j=high;
	while (i<j){
		if(x==(a[i]+a[j])){
			return true;
		}else if(x<(a[i]+a[j])){
			--j;
		}else{
			++i;
		}
	}
	return false;

}


int main()
{
	srand(time(NULL));
	int count;
	while ((count=rand()%20)<3);
	int *a=new int[count];

	for(int i=0;i<count;++i){
		a[i]=rand()%35;
		cout<<a[i]<<" ";
	}
	cout<<endl;

	merge_sort(a,0,count-1);

	for(int i=0;i<count;++i){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	int x=rand()%100;
	bool flag=sum_to_x(a,0,count-1,x);

	cout<<x<<" is in S ? "<<boolalpha<<flag<<endl;


}



  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值