题解:消失的两个数字(位运算算法)
目录
1.题目
题目链接:LINK
2.题解
本题要求时间复杂度O(N),空间复杂度O(1),分别否了我们 排序遍历 和 哈希数组 的想法。想要在规定时间/空间复杂度内完成本题,需要借用 位运算算法。
具体该如何操作呢?
①首先,我们将 原数组 与 [1,n+2] 的数字全部 异或起来 ,这时候会得出 ret = a ^ b
②根据ret,我们可以知道 a 与 b 的不同的一位二进制 ,我们根据这位不同的二进制来区分a 和 b
③让 原数组 和 [1,n+2] 数字根据不同的这一二进制位 站队 ,再把两队全部异或起来消去相同的一项得出a 和 b,因为a 和 b只在[1,n+2]中出现过一次因而不会被异或掉。
可能单纯叙述有点抽象,我直接用一个例子来说明我上面说的步骤:
3.示例代码如下
cpp
class Solution {
public:
vector<int> missingTwo(vector<int>& nums)
{
int ret = 0;
for(auto& num : nums) ret ^= num;
for(int i = 1; i <= nums.size()+2; i++) ret ^= i;
//ret = a ^ b
int count = 0;
while(1)
{
if(((ret >> count) & 1) == 1) break;
else count++;
}
int a = 0;
int b = 0;
for(auto& num: nums)
{
if(((num >> count) & 1) == 1) a ^= num;
else b^=num;
}
for(int i = 0; i <= nums.size()+2; i++)
{
if(((i >> count) & 1) == 1) a ^= i;
else b^=i;
}
return {a,b};
}
};
4.总结
这道题整体的思路是这样的,我们先找出ret = a ^ b来,主要是为了确定这俩数字哪个二进制位不一样,方便将其归纳到不同的组中去,两个消失的数字归纳到不同的组之后我们可以用异或的两两相消原理,把重复的数字全部干掉,一组只剩下a,一组只剩下b,返回即可。
拓展:位运算常用操作:LINK
EOF