一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出这两个只出现一次的数字。

要求时间复杂度是O(n),空间复杂度是O(1)。

思路:

1.通过异或运算,可以消除两个相同的数: A ^ A = 0

2.若一组数中仅有一个数字出现一次,其它数字均出现两次,将这组数字逐个做异或运算,结果就是仅出现一次的数字。

3.数组中有两个仅出现一次的数字,其它数字均出现两次,所以最终异或结果即为这两个数异或的结果。
4.这个结果中右起第一个不为1的位(第n位)表示这两个数的该位不一致,一个为0一个为1
5.现在要设法把这两个数分到不同的两个组里,同时保证组内其它数字均出现两次
6.按照第n位为0或1进行分组,这样可以保证这两个数可以分在不同的组,同时也保证相同的两个数分在同一个组。

7.这样就转化为2.所述问题,得解。


参考代码(转载)

#include <stdio.h>
int main() {
int a[] = {1, 2, 0, 2, 1, 9, 3, 9, 0, -1};
int number1 = 0, number2 = 0;
int i = 1, tmp = a[0], index = 0;
for (; i < sizeof(a)/sizeof(*a); ++i) {  //得出 3 ^ -1
tmp ^= a[i];
}
number1 = tmp;  
number2 = tmp;  
// number1 = 0;
// number2 = 0;
// number1 = tmp;  number2 = tmp; 时,number累积异或的结果为出现在另一组的那个数
// number1 = 0;  number2 = 0; 时,number累积异或的结果为出现在本组的那个数

while (tmp) {                    //找出tmp从右数第一个为1的位置
if (1== (tmp & 1)) {
break;
}
++index;
tmp >>= 1;
}
for (i = 0; i < sizeof(a)/sizeof(a[0]); ++i) {  //以index位为1将数组分成两部分,每部分只含有一个只出现一次的数字
if (1 == ((a[i] >> index) & 1)) {           //得到一个
number1 ^= a[i];                          
}
else {                                      //得到另外一个
number2 ^= a[i];
}
}
printf("%d  %dn", number1, number2);
return 0;
}



            原创文章,转载请注明: 转载自    编程小径

          本文链接地址: http://blog.csdn.net/imbing/article/details/8217289




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值