您的位置:首页 > 其它

微软:找出数组中和为N+1的的组合个数

2014-06-16 14:00 232 查看
一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。

设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于N+1。

复杂度最好是O(n),如果是O(n2)则不得分。

这题我一直在思考,确实想不到时间复杂O(n)的方法,后面用基数排序先把数组排序了一下,再做,时间复杂度是O(nlogr(M))。

用这中方法做这道题题目一个比较尴尬的事情是,它是时间复杂度是不固定的,有可能超过O(n^2),比如N=1000,而整数列里只有两个数字,问题大家可想而知。

后来网上看了一下,有人是通过快排方法对数组进行排序的,时间复杂度是O(n(log2)n)。

排序好之后,弄一个头指针和尾指针

if arr[font]+arr[back]==N+1 then count++, back--, font ++

else if >N+1 then back--; //说明尾数过大,要缩小

else font++; //同理

/*
这题的话,我是通过制造N/2+1个桶出来,两数和为N+1的数放在一起,
然后遍历桶,其中为 2 的则有一对数字和为 N+1,因为数字不会重复嘛
不过我比较担心的一点是,题目中说的N是一个比较大的数,究竟有多大呢?
万一很大,我申请的动态数组有可能会崩溃,这样就计算不出结果了。
时间复杂度为O(n)+O(N/2)
*/

#include<stdio.h>
#include<malloc.h>
#include<string.h>

int main()
{
int arr[14]={1,2,3,4,6,7,8,9,12,24,13,15,16,10};

int N=18;
int len=sizeof(arr)/sizeof(int);
int *p=(int *)malloc(sizeof(N/2+1));
if(p==NULL)
return -1;

memset( p,0, sizeof(int)*(N/2+1));
//后面为什么是sizeof(int)*(N/2+1)而不是(N/2+1)呢?
//有兴趣的读者memset(p.0 ,N/2+1);后输出来看看结果

//count用于计算对数
int count=0;
int i=0;

//这边的话其实还可以用头尾指针往中间走,不过要是遇到奇数个数,
//判断起来会比计较麻烦
for(;i<len; i++ )
{
if(arr[i]<(N+1)/2)
(*(p+arr[i]-1))++;
else
(*(p+N-arr[i]))++;
}

for(i=0;i<N/2+1;i++)
{
if(*(p+i)==2)
{
count++;
printf("%d ",i);
}
}
getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: