136;
题意很简单,给你一个数组(int),只有一个数字是出现一次的,其余出现两次,不允许使用额外空间,时间复杂度线性。
如果允许使用额外空间的话,可以使用map记录次数,最后遍历,也是O(n)的复杂度;但是现在需要把额外空间也去掉,我们只能向位操作方面想了。
利用异或的特点,可以发现
(1) a^a =0
(2) 0^ b=b
所以,相同的两个数异或结果肯定是0,而0与唯一的出现一次的数的异或结果是这个数;即对数组进行异或操作,结果就是答案。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res=0;
for(int i=0;i<nums.size();i++)
res^=nums[i];
return res;
}
};
137:
是上一题的加强版,给你一个数组(int),只有一个数字是出现一次的,其余出现三次,不允许使用额外空间,时间复杂度线性。
(先来一个比较通用的,可以求其余出现n次(只需要取余n)的程序,但是用了很小的额外空间)
异或的思路肯定是不行了,但是我们可以继续考虑位运算,如果一个数出现了3次,那么他的对应的二进制位上1的次数一定是3的整数倍,一旦取余之后不是0,那么肯定是出现一次的那个数。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int bitsum[32];
memset(bitsum,0,sizeof(bitsum));
for(int i=0;i<nums.size();i++)
for(int j=0;j<32;j++)
bitsum[j]+=(nums[i]>>j)&1;
int res;
for(int i=0;i<32;i++)
res|=(bitsum[i]%3)<<i;
return res;
}
};