您的位置:首页 > 其它

整数数组中,每个元素均出现两次,除了一个元素例外,如何找出这个元素?能否设计一个线性时间的算法,且不需要额外的存储空间?

2016-12-10 20:46 966 查看
整数数组中,每个元素均出现两次,除了一个元素例外,如何找出这个元素?能否设计一个线性时间的算法,且不需要额外的存储空间?

int singleNumber(int arr[], int n)
{
printf("n = %d\n",n);
int result = 0;
for(int i=0; i < n; i++)
{
result ^= arr[i];
}

return result;
}


 下面是用c语言实现的方法:

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

int singleNumber(int arr[], int n)
{
int result = 0;
for(int i=0; i < n; i++)
{
result ^= arr[i];
}

return result;
}

void main()
{
int arr[5];
int single_Num ;
printf("please input array number:\n");
for(int i = 0; i < 5; i++)
scanf("%d", &arr[i]);
for(i = 0; i < 5; i++)
printf("arr[%d]=%d \n",i, arr[i]);

single_Num = singleNumber(arr, 5);

printf("single number is:%d\n",single_Num);
}


如果是每个元素均出现k次的话,除了一个元素例外,如何找出这个元素?

考虑每个元素的为一个32位的二进制数,这样每一位上出现要么为1 ,要么为0。对数组,统计每一位上1 出现的次数count,必定是kN或者kN+1 次。让count对k取模,能够获得到那个只出现1次的元素该位是0还是1。

例如k等于3的时候,实现方法如下:

int singleNumber(int arr[], int n)
{
int result = 0;
for(int i = 0; i < 32; i++)
{
int count = 0;
int mask = 1 << i;

for(int j = 0; j < n; j++)
{
if(arr[j] & mask)
{
count++;
}
}

if(count % 3)
{
result |= mask;
}
}

return result;
}

网上还有其他的一种算法可以进行参考:
int singleNumber(int A[], int n)
{
int one = 0, two = 0;
for (int i = 0; i < n; i++)
{
two |= A[i] & one;
one ^= A[i];
int three = one & two;
one &= ~three;
two &= ~three;
}
return one;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐