提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
只出现一次的数字|||
给定一个整数数组 nums
,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
示例 1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
示例 2:
输入:nums = [-1,0]
输出:[-1,0]
示例 3:
输入:nums = [0,1]
输出:[1,0]
提示:
2 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
除两个只出现一次的整数外,nums 中的其他数字都出现两次
一、解题分析
1.先将所有数进行异或操作得到x
根据异或指令的性质,两个相同的数异或为0
例如:
0000 0000 0000 0001
0000 0000 0000 0001 异或得
0000 0000 0000 0000
2.因为两个不相同的数异或得到的数某一位肯定存在为1,定义一个整数m,记录第一次出现的为1的位数
3.将数组nums中的元素与1左移m位的数相与,分成两组只出现一次的数分别在不同的数组中。
再用整数x1,x2分别与两个数组中的数异或,最后得到的数分别是数组nums中出现一次的数。
二、代码
int* singleNumber(int* nums, int numsSize)
{
int i = 0;
int x = 0;
int x1 = 0;
int x2 = 0;
for(i=0;i<numsSize;++i)
{
x^=nums[i];
}
uint32_t m = 0;
while(m < 32)
{
if(x & ((uint32_t)1<<m)) //1 默认是 int 需要强制类型转换,否则会报错
{
break;
}
else
m++;
}
for (i=0;i<numsSize;++i)
{
if(nums[i]&((uint32_t)1<<m))
{
x1^=nums[i];
}
else
{
x2^=nums[i];
}
}
int *retArr=(int*)malloc(sizeof(int)*2);
retArr[0]=x1;
retArr[1]=x2;
return retArr;
}