这次是有两个数字只出现了一次,上次只出现了一次那个一个思路是用异或做的,还一个思路是根据i和i-1的对应关系改变值的正负(是在数组的值都在下标范围内才可以这样做),这次这个嘛,let me think think,还要求线性时间复杂度,常数空间复杂度
用Map的话,就不是常数空间复杂度了吧,,
没想出来,看了一下discussion,真是,,惊为天人啊,,,想法好奇,使用了两次异或XOR
两次异或:第一次异或得到一个结果diff,然后找出diff中最后一位为1,比如叫set_bit(其实哪一位无所谓,只要是那一位不同就可以了,因为特殊的那两个数是不一样的,所以必定至少有一位异或之后是1,所以一定存在一位1);
在set_bit这位上为1的数字一定为偶数个,为0的数字一定也为偶数个(除了那两个特殊的),所以第二次异或,set_bit位上为1 的进行异或,得到两个特殊数中的set_bit为1 的那个,set_bit位上为0 的进行异或,得到两个特殊数中的set_bit为0 的那个
如下:(错误的)
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
vector<int> res = { 0 , 0 };
int l = nums.size();
int diff = accumulate( res.begin() , res.end() , 0 , bit_xor<int>());
diff &= -diff; // 找到最后为1的那位
for( int num : nums ){if( (num & diff) == 0 )
res[ 1 ] ^= num;
if( (num & diff) == 1 )
res[ 0 ] ^= num;
}
return res;
}
};
(正确的)
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int diff = accumulate( nums.begin() , nums.end() , 0 , bit_xor<int>());
diff &= -diff;
vector<int> res = {0,0};
for( int num : nums ){
if( (num & diff) == 0 )
res[ 1 ] ^= num;
else
res[ 0 ] ^= num; // !!!!!!!!
}
return res;
}
};
这里真的要注意,,异或完了不是非0即1,因为最后一位1不一定在最低位,有点浮躁,不得行,吃个饭,回来写下一道题
刚要走,突然想起来,还有一个点就是我在粘贴代码后不能跑,百度了一下,是因为,粘贴的时候空格格式不对==
感想:
果真是厉害的代码都千篇一律的简洁&优美
烂代码各有各的bug