题目
难度中等486收藏分享切换为英文接收动态反馈
给定一个整数数组 nums
,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
技巧
1、用异或操作进行消重
2、x & -x == x & (~x + 1)可以得到x中最低的一位1(分析过程看编程小记—— C/C++中 x & -x 表示含义_逗神大人的博客-CSDN博客_x&-x)
题解
通过把所有的数进行异或操作,可消去出现两次的元素,得到只出现一次的两个元素的异或结果。
即x=x1⊕x2,在进行x & -x操作可获得x中最低的一位1,记作l位,x1和x2在l位上,一个是0一个是1。
那么我们可以将所有数分为两类,一类是在l位上是1,一类是在l位上是0。再将类内所有元素进行异或操作,就可以获得x1,x2。
代码
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int xorsum = 0;
for (int num: nums) {
xorsum ^= num;
}
// 防止溢出
int lsb = (xorsum == INT_MIN ? xorsum : xorsum & (-xorsum));
int type1 = 0, type2 = 0;
for (int num: nums) {
if (num & lsb) {
type1 ^= num;
}
else {
type2 ^= num;
}
}
return {type1, type2};
}
};