您的位置:首页 > 其它

[数字技巧]重复数字统计算法的空间优化

2013-08-29 15:54 295 查看
  今天在微博上看到的一道面试题,觉得非常有意思,特记录下来。

  原题是这样的:

给定数组A,大小为n,数组元素为1到n的数字,不过有的数字出现了多次,有的数字没有出现。请给出算法和程序,统计哪些数字没有出现,哪些数字出现了多少次。能够在O(n)的时间复杂度,O(1)的空间复杂度要求下完成么?

  这道题目最大的难点就在于时空限制,确切的说是空间限制,如果没有空间复杂度为O(1)的要求,我们很容易想出用一个hash表来记录元素的出现次数。实现的代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int a[1001];
int n;

void solve3()
{
int i;
for(i=1; i<=n; i++)
{
a[a[i]%(n+1)] += (n+1);
}
for(i=1; i<=n; i++)
{
printf("%d\n",a[i]/(n+1));
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);

scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
solve1();

return 0;
}


View Code
  这个算法中也涉及到一个"大数"k,代码中取值为n+1,事实上,与上面类似,这个值k必须大于n。原因如下:

  原因1:只有a[i]<k才能保证a[i] % k是不变的

  原因2:最后每一个元素表示为a[i] = x + f*k,其中x<k,并且f就是我们要统计的频率。

  其实,这道题的核心思想就是让元素出现在该出现的位置,陈利人老师出过另外一道题是最小没出现的正整数,与这个有点类似。题目如下:

  给定一个无序的整数数组,怎么找到第一个大于0,并且不在此数组的最小整数。比如[1,2,0] 返回 3, [3,4,-1,1] 返回 2。最好能O(1)空间和O(n)时间。

  CSDN上有人给出详细的题解,有兴趣的可以看看:http://blog.csdn.net/ju136/article/details/8153274

  写得不好,如有错误或表述不清楚的,希望大家指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: