只出现一次的数
- 题目:给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
示例 1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
示例 2:
输入:nums = [-1,0]
输出:[-1,0] - 分析:可以利用异或求解.设定变量ret=0,与数组中所有的数异或,得到的最终的ret=x^y,即数组中只出现一次的两个数的异或值.
下面我们该考虑如何将两者分离.
根据rat,查找到它二进制形式下任意一位"1",找到他的位置,根据异或可知,此位置上x与y分别为0和1;由此我们可以将他们分成两组,从而将题目分解成求一个数组中,所有的数都是成对出现,只有一个数是单着的,求出这个单着的数.如此,便可以求出x,y. - java:
class Solution {
public int[] singleNumber(int[] nums) {
//先求出x^y,即0与数组中所有数异或的结果m;
int m=0;
int len=nums.length;
for(int i=0;i<len;++i){
m^=nums[i];
}
//求出m的二进制数中任意一个1的位置,这个"1"代表着 x与y的二进制数在这个位置上一个为0另一个为1;
//以此可以区分x与y,并将其余的数按照这个分成两组
//如此的话,这个问题就将变成,一个数组中所有数都是成对的,求出那个单着的
int n=0;//代表m的二进制数在第n个位置上是1
while(n<36){
if((m&(1<<n))!=0)
break;
else
n++;
}
int x=0;
int y=0;
for(int i=0;i<len;++i){
if((nums[i]&(1<<n))!=0){
x^=nums[i];
}
else {
y^=nums[i];
}
}
int[] array={x,y};
return array;
}
}
C:
int* singleNumber(int* nums, int numsSize, int* returnSize){
int ret=0;
for(int i=0;i<numsSize; ++i){
ret ^=nums[i];
}
int m=0;
while(m<32){
if(ret & (1<<m))
break;
else
++m;
}
int x=0;
int y=0;
for(int i=0;i<numsSize;++i){
if(nums[i]&(1<<m)){
x^=nums[i];
}
else{
y^=nums[i];
}
}
int* retArr =(int *)malloc(sizeof(int)*2);
retArr[0]=x;
retArr[1]=y;
*returnSize=2;
return retArr;
}