题目:
分析:
- 之前我们做过一道类似的题目: <消失的一个数字>, 我们用的办法是用数组中的每个数字与带上消失的数字的数组中的数字进行^, 这样就得到了消失的数字
- 但是我们这道题目, 如果按照上述方法, 得到的是两个数字a和b的^, 那么我们怎么将两个数字分开呢?
- 其实后面就是<只出现一次数字III>的思路:
- 对于异或后的结果, 如果某一bit位上是1, 说明这两个数字肯定是不同的, 因为^的规则是相同为0,相异为1
- 那么我们可以根据这个特性, 将我们上述异或在一起的所有数字进行分组, 这一位bit位上为1的是一组, 为0的是一组, 那么每一组中, 一定是一个数字出现一次和其他数字出现两次的情况, 那么我们对每一组在进行异或, 就得到了这两个数字
总结分为以下三步:
- 将所有的数异或在一起
- 找到tmp上bit位为1的那一位x
- 根据x位的不同, 或分成两组分别异或
代码:
java
class Solution {
public int[] missingTwo(int[] nums) {
//1
int tmp = 0;
for (int x : nums) {
tmp ^= x;
}
for (int i = 1; i <= nums.length + 2; i++) {
tmp ^= i;
}
//2
int diff = 0;
while (true) {
if (((tmp >> diff) & 1) == 1)
break;
else
diff++;
}
//3
int[] ret = new int[2];
for (int x : nums) {
if (((x >> diff) & 1) == 1) {
ret[1] ^= x;
} else {
ret[0] ^= x;
}
}
for (int i = 1; i <= nums.length + 2; i++) {
if (((i >> diff) & 1) == 1) {
ret[1] ^= i;
} else {
ret[0] ^= i;
}
}
return ret;
}
}