题目:给出一个整形数组,数组中的数据只有一个数是单个的,其他的数都有两个,返回这个单个的数。
解决方法:1. 先将数组排序,如果这个数的左边和右边均与这个数不相等,那么这个数就是要返回的数。这种实现方法的时间复杂度是O(n),其中n为数组中的元素个数,并且没有浪费多余的空间。
class Solution {
public:
int singleNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
int len=nums.size();
if(nums[0]!=nums[1])
return nums[0];
if(nums[len-2]!=nums[len-1])
return nums[len-1];
for(int i=1;i<len-1;i++){
if(nums[i]!=nums[i-1]&&nums[i]!=nums[i+1])
return nums[i];
}
return 0;
}
};
2.用C++中的STL容器set实现,这种方式浪费空间,因为定义了一个set。
class Solution {
public:
int singleNumber(vector<int>& nums) {
set<int> s;
int len=nums.size();
for(int i=0;i<len;i++){
if(s.find(nums[i])!=s.end())
s.erase(nums[i]);
else
s.insert(nums[i]);
}
auto iter=s.begin();
return *iter;
}
};
或者用STL容器map也可以实现,但是这种方式不仅浪费空间,而且还要遍历一次数组,再遍历一次map容器。显然更不好。
class Solution {
public:
int singleNumber(vector<int>& nums) {
map<int,int> m;
int len=nums.size();
for(int i=0;i<len;i++){
auto iter=m.find(nums[i]);
if(iter!=m.end())
iter->second++;
else{
pair<int,int> value(nums[i],1);
m.insert(value);
}
}
auto iter2=m.begin();
for(;iter2!=m.end();iter2++){
if(iter2->second==1)
return iter2->first;
}
return 0;
}
};