说实话Single Number II 和 III 都让人感觉到异常的头疼。虽然都是位操作但是方式又不太一样,特别是II。
这一题相对来说,对位操作的要求并非太高。用的和Single Number I一样是基于异或的操作。但是又复杂一些。
首先我们看一下,假设这两个特立独行的数字分别是a和b的话,把所有数字做第一次异或操作,你最后得到的就是a ^ b
从a ^ b之中,我们可以得到a和b之间有哪些bit是不一样的,知道这个,其实就可以把数组的数分成了两组,这些bit我们任意取一个出来就可以了,以这个为区分点,这个bit上为1的是其中一组,为0的是另一组,这样这两组异或出来的结果,就是答案a和b了。
为了方便,可以取least significant bit。取least significant bit 的方法是 lsb = num & ~(num - 1)。给出代码如下:
public int[] singleNumber(int[] nums) {
int xor = 0;
for (int num : nums) {
xor ^= num;
}
int lsb = xor & ~(xor - 1);
int[] result = {0, 0};
for (int num : nums) {
if ((num & lsb) == 0) {
result[0] ^= num;
} else {
result[1] ^= num;
}
}
return result;
}