数组中数字出现的次数
题目描述:一个整型数组里除了两个数字之外,其他数字都出现两次。
要求:时间复杂度为O(n),空间复杂度为O(1)
思路:数组中只有两个出现次数为一次的数,其余数都是两两出现,本题可以通过有异或来进行求解;首先可以将数组里面的数进行一次异或,得到的结果是两个只出现一次的数的异或值;第二步,找出异或后二进制位的第一个位为1的位,然后将数组中的值进行划分,这样会将这两个出现一次的数分别划分在不同的数组中;第三步,分别对两个数组进行异或,便可求得数组中两个出现次数位一次的数字。
举例说明:
{4,1,4,6}
4:0100
1:0001
4:0100
6:1100
可以知道:4 ^ 4 = 0(异或,相同位,相同为0,相异为1)
所以数组异或结果为 1101
可以发现1和6可以通过二进制位第一个为1的位划分开
第一个 数组:0001(1)
第二个数组:0100 0100 1100(4,4,6)
分别异或就得到0001和1100,就是结果1,6
代码实现
vector<int> singleNumbers(vector<int>& nums) {
int len = nums.size();
vector<int> ret(2,0);//用于对最终的异或结果进行保存
int temp = 0; // 用于对nums数组进行一遍异或运算
for(int i=0;i<len;i++)
{
temp = temp^nums[i];
}
// 寻找temp二进制第一个为1的位置
int pos = 0; //pos记录右移的位数个数
while((temp&1)!=1)
{
pos++;
temp = temp>>1;
}
//根据该pos位置将nums分为两部分,直接进行位运算
for(int i=0;i<len;i++)
{
if((nums[i]>>pos)& 1 == 1)//找到所有数种二进制位第一次出现一的数,进行异或
{
ret[0] = ret[0]^nums[i];
}
else
ret[1] = ret[1]^nums[i];
}
return ret;
}