题目:请给出一个运行时间为Θ(nlgn)的算法,使之能在给定一个由n个整数构成的集合S和另一个整数x时,判断出S中是否存在有两个其和等于x的元素。

加上了我自己的一点想法,原文为转载


第四种方法:

1、构造一个跟S大小一样大的向量T   O(1)

2、将X –S[i]都放进T去,              O(n)

3、构造一个M[2*n]大小的数组,然后将S和T采用归并排序的思想插入                               O(nlgn)

剩下的事情就是将比较集合T中是否存在至少有连续的元素相同,如果有则存在这样的两个元素其和为X,否则不存在,    O(n)


第三种方法:

思路:排序加索引,但是这个索引的复杂度为O(n), 具体为,先对数组进行排序,采用MergeSort或者QuickSort都行(此处考虑的是时间复杂度,空间的复杂度暂时不计)复杂度为O(nlgn),然后设置两个游标从一个为start一个为end,然后start从前往后,end从后往前,对整个序列进行遍历,(设当前要查找value,集合为S,集合中是否有两个数加一起等于它),用delta = X-S[m],如果delta>S[n] 则要求m++,若小于则要求n--,否则相等则输出,结果

code :

# include <stdio.h>
# include <malloc.h>
# define MAX   111111111
/*
by--Acton
2013年9月18日12:40:42
*/
void MergeSort(int a[], int start, int end  );
void Findnumbers(int a[],int start, int end , int val );


int main(void){

	int a[] = {1,2,3,4,5,6};
	int want_find ;
	want_find = 7;
	MergeSort(a,0,5);
	for (int i = 0 ; i< 6; i ++){
		printf("%d  ",a[i]);
	}
	printf("\n");
	Findnumbers(a,0,5,want_find);

	return 0;
}

void Merge(int a[], int start , int mid ,int end){

	int nl = mid -start+1;
	int nr = end-mid ;
	int *R = (int*)malloc(sizeof(int)*nr);
	int *L = (int*)malloc(sizeof(int)*nl);

	for(int i = 0 ;i <nl;i++){
		L[i] = a[start+i];
	}
	L[nl] = MAX;
	for (int j = 0; j < nr; j ++){
		R[j] = a[mid+1+j];
	}
	R[nr] = MAX;

	i = 0 ;
	j = 0; 
	int k = start;
	while(k <= end){
		if (L[i] < R[j]){
			a[k] = L[i];
			i ++;
		}else{
			a[k] = R[j];
			j ++;
		}
		k ++;
	}
}

void MergeSort(int a[], int start, int end  ){
	if (start < end){
		int mid=(start+end)/2;
		MergeSort(a,start,mid);
		MergeSort(a,mid+1,end);
		Merge(a,start,mid,end);
	}
}

void Findnumbers(int a[],int start, int end , int val ){
	
//	MergeSort(a,0,5);
	int m = start;
	int n = end;

	while (m < n ){
		if (val-a[m] < a[n]){
			n --;
		}else if (val-a[m] > a[n]){
			m ++;
		}else{
			printf("%d + %d = %d\n",a[m],a[n],val);
			n--;
		}
	}




	return ;
}



  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值