class Solution {
public:
int singleNumber(vector<int>& nums) {
int res=0;
for(int i=0;i<nums.size();i++){
res^=nums[i];
}
return res;
}
};
面试问我这个,不能占用空间,没刷题还真不一定知道(面试一定要多刷题再上,跟高考一样的,不能存有侥幸心理,除非,啥题没见过都会的那种大神。。。不得不承认自己是个菜鸡)
异或操作,a^b,如果a和b相等,结果为1,如果a和b不想等,结果为0 ,所以,全员异或,相等元素异或都化为0了,结果就剩下那一个形单影只的了。
进阶版:
除了一个出现1次,其余均出现3次,利用不重复set,求和*3-2*nums就是两倍的目标。提交代码没过。。应该是溢出了
class Solution {
public:
int singleNumber(vector<int>& nums) {
unordered_set<int> res(nums.begin(),nums.end());//不重复set的初始化,可以通过begin-end
return (3*accumulate(res.begin(),res.end(),0)-accumulate(nums.begin(),nums.end(),0))/2;
}
};
改成自己写求和函数:
class Solution {
public:
int singleNumber(vector<int>& nums) {
unordered_set<int> res(nums.begin(),nums.end());//不重复set的初始化,可以通过begin-end
return (3*sum(res)-sum_v(nums))/2;
}
long sum(unordered_set<int> res){
long re = 0;
unordered_set<int>::iterator it= res.begin();
while(it!=res.end()){
re+=*it;
it++;
}
return re;
}
long sum_v(vector<int> res){
long re=0;
for(int num:res){
re+=num;
}
return re;
}
};
https://leetcode-cn.com/problems/single-number-iii/
有两个出现1次,其余出现2次,先将全部按位异或,得到的是两个数不等的二进制位为1,从右侧到左侧,找到第一个等于1的二进制位下标,这个位可以将两个数分离开,分成两部分,两部分中其余数都是成对的,这样再分别两部分异或就得到解了。
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int res=0;
for(int num:nums)
res ^= num;
int idx=0;
while(((res>>idx) & 1)==0) idx++;
int res1=0,res2=0;
for(int num:nums){
if((num>>idx) & 1) res1 ^= num;
else res2 ^= num;
}
vector<int> re;
re.push_back(res1);
re.push_back(res2);
return re;
}
};