AcWing 73. 数组中只出现一次的两个数字
原题链接
中等
作者:
ITNXD
,
2021-04-30 23:09:27
,
所有人可见
,
阅读 387
这波操作属实秀
思路:
- 相同的两个数异或为0
- 因此,第一步将所有数异或最终结果就是两个只出现一次的数的异或结果,记为 x & y
- 为了将 x y 分开,我们得找到一个突破点?
- 只出现一次的两个数一定不一样,则至少有一位二进制,一个为0一个位1
- 因此,直接从sum中随便找到一个不同点(不同点的异或结果为1)
- 则我们可以将原数字序列分为两部分:一部分为第k位为1,一部分为第k位为0
- 而只出现一次的两个数x,y则分别位于这两个部分!
- 因此,就转换为了一个序列只有一个数出现一次,其余出现两次的问题!
- 则直接在该部分进行一次异或,相同的数两两抵消,则剩下的就是只出现一次的数!
- 对sum在进行一次异或(异或刚找到出现一次的数)抵消后即可得到另一个出现一次的数!
参考代码:
class Solution {
public:
vector<int> findNumsAppearOnce(vector<int>& nums) {
int sum = 0;
for(auto x : nums) sum ^= x;
int k = 0;
while(!(sum >> k & 1)) k ++;
int s = 0;
for(auto x : nums) if(x >> k & 1) s ^= x;
return {s, sum ^ s};
}
};