题目
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
输入: nums = [4,1,4,6]
输出: [1,6] 或 [6,1]
由于计算机的每一个二进制都代表一个数字,那么相同的数字,其二进制是一样,利用异或运算,其两个相同的数字异或为0。那么只有不同数字才不为0。
101 ^ 101 = 000 5^5
101 ^ 001 = 100 5^1
那么对于只有一个不重复数字来说,我们只需要求异或就可以。
那么对于两个来说,我们需要将两个不重复的值分在两组数组里,并且相同的数要在相同的组里。
对于不同数字 那么异或必定会存在1,则就是辨别其不同的地方,我们利用某一位为1,进行区分。
[4,1,4,6]
4^4^1^6
= 0^1^6
=1^6
= 0001 ^ 0110 = 0111
其中任何一个1,都可以区分
以第一个1 [4,4,6] [1]
以第二个1 [4,4,1] [6]
class Solution {
public int[] singleNumbers(int[] nums) {
int n = nums.length;
int res =0 ;
for(int i=0;i<n;i++){
res ^= nums[i];
}
int h=1;
while((h & res) == 0){
h <<=1;
}
List<Integer> l1 = new LinkedList<>();
List<Integer> l2 = new LinkedList<>();
for(int i=0;i<n;i++){
if((h&nums[i])!=0){
l1.add(nums[i]);
}else{
l2.add(nums[i]);
}
}
int a = 0;int b=0;
for(int i=0;i<l1.size();i++){
a^=l1.get(i);
}
for(int i=0;i<l2.size();i++){
b^=l2.get(i);
}
return new int[]{a,b};
}
}