有一个数组,各种数组出现次数的神组合……
来源:互联网 发布:真实赛车3车辆数据排行 编辑:程序博客网 时间:2024/05/16 16:00
1. 基本款:有一个数出现了一次。其余的数都出现了两次
异或,结果就是只出现一次的数。
2. 进阶款1 有一个数出现了一次。其余的数都出现了三次
基本思想: 假设是32位的整数,定义一种新的bit operation 。 每位操作如下: 1^0=1, 0^1=1, 0^0=0, 1^1=2, 2^1=0...每次按位操作,一直到最后。
每次操作32次。 复杂度32n, 还是O(n)的 (感慨以下,李博好聪明,果然是MS的人)
(可以用一个长度为32的数组,每一个value存储对应bit的运算结果)
careercup上的解法,太牛了
for( i=0; i< 10; i++ ){x = B[i];twos |= ones & x ;ones ^= x ;not_threes = ~(ones & twos) ;ones &= not_threes ;twos &= not_threes ;}printf("\n unique element = %d \n", ones );return 0;
思想:one用来存储只出现一次bit,two用来存储出现两次的bit。
twos |= ones & x由于one只存储了出现一次的bit,因此此时two保留了出现两次的bit,并且可能含有出现三次的bit
ones ^= x ;包含了出现一次和三次的bit信息,
not_threes = ~(ones & twos) ;ones &= not_threes ;twos &= not_threes ;删除one two中出现三次的bit信息。
3. 进阶款2 有两个数出现了一次。其余的数都出现了两次
参考基本款,如果能够把原数组分为两个子数组。在每个子数组中,包含一个只出现一次的数字,而其他数字都出现两次。如果能够这样拆分原数组,按照前面的办法就是分别求出这两个只出现一次的数字了。
我们还是从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次,在异或中全部抵消掉了。由于这两个数字肯定不一样,那么这个异或结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为1。我们在结果数字中找到任一个为1的位的位置,记为第N位。现在我们以第N位是不是1为标准把原数组中的数字分成两个子数组,第一个子数组中每个数字的第N位都为1,而第二个子数组的每个数字的第N位都为0。
现在我们已经把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其他数字都出现了两次。因此到此为止,所有的问题我们都已经解决。
int* twoTwice(int * A, int size){int * result = new int[2];result[0] = 0;result[1] = 0;for(int index=0; index<n; index++)result[0] ^= A[index];int mask = 1;while (result[0] & mask)mask = mask<<1;result[0] = 0;for(int index=0; index<n; index++) {if (A[index] & mask == 0)result[0] ^= A[index];elseresult[1] ^= A[index];}return result;}
程序牵扯几个小问题:
a. 返回数组时,返回指针。另外,数组内别忘了new memory
b. 如何寻找某一位为1,并产生mask(一步操作即可,简单)
- 有一个数组,各种数组出现次数的神组合……
- 数组中有一个数字出现的次数超过数组长度的一半......
- 数组中有一个数字出现的次数超过数组长度的一半
- 数组中有一个数字出现的次数超过数组长度的一半
- 数组中有一个数字出现的次数超过了数组长度的一半,找出这个数
- 数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。
- 面试:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数
- 数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字
- 数组中有一个数字出现的次数超过了数组长度的一半,请找出这个数。java实现
- C++数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。
- C++数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。(牛客剑指offer)
- 【c语言】数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
- 数组中有一个数字出现的次数超过了数组长度的一半,请找出这个数字。
- 数组中有一个数字出现的次数超过了数组长度的一半,找出这个数
- 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
- 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
- 数组中有一个数字出现的次数超过了数组长度的一半,找出这个数
- 数组中有一个数字出现的次数超过了数组长度的一半,找出这个数
- FusionCharts Free中文开发指南 第八章--FusionCharts Free和组合图XML
- linux音频alsa-uda134x驱动分析之二(时钟)
- Launching Tasks in the Foreground and Background
- 二分插入排序算法的C/C++实现
- FusionCharts Free中文开发指南 第九章--动态改变图形的类型和数据
- 有一个数组,各种数组出现次数的神组合……
- FusionCharts Free中文开发指南 第十章--FCF中的下钻
- PLAY2.0框架快速入门
- UITableView实现双击事件的方法
- c++ primer 13.4
- java中this的使用
- [Git]将remote branch强制更新到local branch
- 主机字节序与网络字节序
- R文件不会自动更改问题的解决