本文参考 微信号为:”待字闺中“ 的信息,感兴趣的可以加一下他的微信。在此对其表示感谢,看过他的文章很受启发,这里只是自己记录下,以防将来忘记,别无它意。
题目:给定数组A ,大小为n,数组元素为1到n的数字,不过有的数字出现了多次,有的数字没有出现。请给出算法程序,统计那些数字没有出现,那些数字出现了多次。能够在O(n)的空间复杂度,O(1)的空间复杂度要求下完成。
分析: 原数组是没有排序的,如果排序了,就简单了。
O(1)的空间含义,可以使用变量,但不能开辟数组或者map来计数。
两种方法:
1 三次遍历: 第一次遍历:对于每一个i A[i] =A[i]*n;
第二次遍历:对于每一个i A[A[i]/n]++;
第三次遍历: 对于每一个i A[i]%n 就是出现的次数
代码如下:
void repetitions(int A[],int n)
{
int i = 0;
int frequency = 0;
int element = 0;
for(i=0;i<n;i++)
{
A[i] = A[i] * n;
}
for(i=0;i<n;i++)
{
A[A[i]/n]++;
}
for(i=0;i<n;i++)
{
frequency = A[i]%n;
element = i;
printf("ELement = %d, frequency = %d\n",element,frequency);
}
}
int main()
{
int A[10]={2,5,4,8,6,3,4,5,9,8};
repetitions(A,10);
return 0;
}
2 二次遍历:
这里我们用到了两个技巧: 1 给数组元素加n,能够保证A[i]%n不变
2 A[i]=x+k*n,其中x代表原数组的值,k代表频率
代码如下:
#include <stdio.h>
#include <stdlib.h>
void repetitions(int A[],int n)
{
int i = 0;
int frequency = 0;
int element = 0;
for(i=0;i<n;i++)
{
A[A[i]%n] += n;
}
for(i=0;i<n;i++)
{
frequency = A[i]/n;
element = i;
printf("ELement = %d, frequency = %d\n",element,frequency);
}
}
int main()
{
int A[10]={2,5,4,8,6,3,4,5,9,8};
repetitions(A,10);
return 0;
}
本人微信号:yuansanwan 微博:http://weibo.com/u/2729471010/home?wvr=5 欢迎一起讨论问题。