题目:在数组中,所有的元素都出现2次,除了某2个元素只出现一次,找出这2个只出现一次的元素。
Given
nums = [1, 2, 1, 3, 2, 5]
, return
[3, 5]
.
分析:
1. 记出现一次的元素为A, B 一个很自然的想法就是选对所有元素进行异或,那么出现2次元素都可以用异或消掉,所以最后剩下 A xor B 的结果,记结果为 R,
所以问题转变成如何将2个异或的值分离出来。
2. 如果结果 R 中有一个位 为 1, 根据异或的原则,那么A,B在该位上的值一定是不一样的。所以,要是能够找到为1 的位,就可以区分了。
3. R中最后一位为1的可以通过 last = R & (R - 1) 得到。
4. 根据last, 我们就可以将所有的元素分成2 组了,last位上为1 的1 组, last 位上为0 的1 组。A 和 B一定能够掉到不同的组里面去的。
每个组内分别进行异或。
5. 重复出现的元素肯定都是掉到同一个组里的,会在组内消掉。最后2个组内,只会分别剩下A 和 B。
复杂度:
时间复杂度:
0(n)
空间复杂度:
0(1)
代码:
public int[] singleNumber(int[] nums) {
int a_xor_b = 0;
for (int num : nums) {
a_xor_b ^= num;
}
// find the last set bit, a differ b
int last = a_xor_b & ~ ( a_xor_b - 1);
// divide all numbers into two groups
// a and b must fall into the two distinct groups
int[] result = new int[2];
for (int num : nums) {
if ((last & num) == 0) {
result[0] ^= num;
}
else {
result[1] ^= num;
}
}
return result;
}