class Solution {
public:
int singleNumber(vector<int>& nums) {
int sum=0;
for(int i=0;i<nums.size();++i) sum^=nums[i];
return sum;
}
};
妈蛋!样例竟然有负数,负数位运算我又不会,计组学的啥也不是,只能都加一个INF,变成正数了哦
class Solution {
#define ll long long
#define INF (1LL<<33)
public:
int singleNumber(vector<int>& nums) {
int n=nums.size();ll ans=0;
for(int j=34;j>=0;--j){
int cnt=0;
for(int i=0;i<n;++i) cnt+=(((ll)nums[i]+INF)&(1LL<<j))?1:0;
if(cnt&1) ans+=1LL<<j;
}
return ans-INF;
}
};
题目
第一种解法:不知道有没有负数,就当有吧
class Solution {
#define ll long long
#define INF (1LL<<33)
public:
int singleNumber(vector<int>& nums) {
int n=nums.size();
ll ans=0;
for(int j=34;j>=0;--j){
int cnt=0;
for(int i=0;i<n;++i) cnt+=((ll)(nums[i]+INF)&(1LL<<j))?1:0;
if(cnt%3) ans+=1LL<<j;
}
return ans-INF;
}
};
第2种解法:
要达到这样的一种效果:
第一次遇见x: one=x,two=0;//这里two并没有等于x
第二次遇见x: one=0,two=x;//这样one并没有等于x^x=0
第三次遇见x: one=0,two=0;
也就是说:
1. one=0,two=0时one才能^x,就是one=x;
2. one=x,two=0时one才能^x,就是one=0;
1. one=0,two=0时two才能^x,就是two=x;
这里(指上一行)可不是第一次遇见one=x,two=0这一种状态过来的哦 因为one比two先被更新,
第二次遇见的时候,没更新two的时候,one被更新成了0)
2. one=0,two=x时two才能^x,就是two=0;
综上所述我们可以看出,two=0时,one才应该被更新,one=0时,two才应该被更新
所以有了one=(one^nums[i]),这是正常的更新限制条件应该是two=0,所以要&(~two);
上面说的情况是对于一个数出现了三次的情况,那么多个数呢,还能这么灵活的位运算吗?
首先one=(one^nums[i])肯定没问题?然后不想想了,先这样吧。。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int one=0,two=0;
for(int i=0;i<nums.size();++i){
one=(one^nums[i])&~two;
two=(two^nums[i])&~one;
}
return one;
}
};