位操作(应该是异或^),目前已知可解决以下问题:
- 数组中,一个元素只出现一次(奇数次),其他出现偶数次;
- 数组中,两个元素只出现一次(奇数次),其他出现偶数次;
解决方法详见这两篇博客:
http://blog.csdn.net/morewindows/article/details/7354571
http://blog.csdn.net/morewindows/article/details/8214003
这里将要介绍的是这样一个问题:
数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次。请给出最快的方法找到x。
解决思路:
如果数组中没有x,那么数组中所有的数字都出现了3次,在二进制上,每位上1的个数肯定也能被3整除。如{1, 5, 1, 5, 1, 5}从二进制上看有:
1:0001
5:0101
1:0001
5:0101
1:0001
5:0101
二进制第0位上有6个1,第2位上有3个1.第1位和第3位上都是0个1,每一位上的统计结果都可以被3整除。而再对该数组添加任何一个数,如果这个数在二进制的某位上为1都将导致该位上1的个数不能被3整除。因此通过统计二进制上每位1的个数就可以推断出x在该位置上是0还是1了,这样就能计算出x了。
推广一下,所有其他数字出现N(N>=2)次,而一个数字出现1次都可以用这种解法来推导出这个出现1次的数字。
代码如下:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
/** @brief * 数组nums中,x出现一次,其他数字都出现了k次 * 以O(1)的空间复杂度,找出x * * @param nums[] int -元素数组 * @param len int -数组长度 * @param k int -除待求数组外,其他元素出现k次 * @return int -返回唯一出现一次的元素 * */ int GetUniqueValue(int nums[], int len, int k) { int bits[32]; memset(bits, 0, sizeof(bits)); /**< 统计数组中所有元素在某一位上1的个数 */ /**< 去除出现k次的数据 */ /**< 由于负数存储的是补码,这里将其转换为原码 */ } /**< 根据二进制位及符号位计算该元素的值 */ return ret; |