题目:
一个整型数组 nums
里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
解答:
思路:
代码:
class Solution {
public int[] singleNumbers(int[] nums) {
int x = 0, y = 0, n = 0, m = 1;
//因为相同的数字异或为0,任何数字与0异或结果是其本身。
//所以遍历异或整个数组最后得到的结果就是两个只出现一次的数字异或的结果:即 n = x ^ y
for (int num : nums) n ^= num;
//m为x和y二进制数第一个不同的位置。
m = n & (~n + 1);
//我们遍历数组,将每个数跟m进行与操作,结果为0的作为一组,结果不为0的作为一组
//例如对于数组:[1,2,10,4,1,4,3,3],我们把每个数字跟1000做与操作,可以分为下面两组:
//nums1存放结果为0的: [1, 2, 4, 1, 4, 3, 3]
//nums2存放结果不为0的: [10]
//此时我们发现问题已经退化为数组中有一个数字只出现了一次
//分别对nums1和nums2遍历异或就能得到我们预期的x和y
for (int num : nums) if ((num & m) != 0) x ^= num;
//因为n=x^y,所以y=n^x=x^x^y=y;
y = n ^ x;
return new int[]{x, y};
}
}