题目描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1] 输出: 1 示例 2:
输入: [4,1,2,1,2] 输出: 4
方法一:vector
基本思路是,创建一个vector,然后将数组中的元素读进去,每次读取之前,先判断里面有没有这个元素,如果没有,那么将这个元素存进去,如果有,那么将它抹去,这样最后剩下来的就是只出现一次的元素。
要注意的是,vector自己没有find函数,所以需要调用algorithm库函数的find,这个函数返回的也是迭代器。vector的erase函数只能根据迭代器来删除,不能直接根据值来删除。
代码语言:javascript复制class Solution {
public:
int singleNumber(vector<int>& nums) {
vector<int>temp;
for(vector<int>::iterator it=nums.begin();it!=nums.end();it ){
if(find(temp.begin(),temp.end(),*it)==temp.end())temp.push_back(*it);
else temp.erase(find(temp.begin(),temp.end(),*it));
}
return *temp.begin();
}
};
切片
代码语言:javascript复制class Solution {
public:
int singleNumber(vector<int>& nums) {
vector<int>temp;
for(auto & i:nums)
if(find(temp.begin(),temp.end(),i)==temp.end())temp.push_back(i);
else temp.erase(find(temp.begin(),temp.end(),i));
return *temp.begin();
}
};
方法二:set
set比vector快很多。
基本思路同方法一,但是由于set自己有find函数,所以比较直接,set的erase函数可以直接根据值来删除。
代码语言:javascript复制class Solution {
public:
int singleNumber(vector<int>& nums) {
set<int>temp;
for(vector<int>::iterator it=nums.begin();it!=nums.end();it ){
if(temp.find(*it)==temp.end())temp.insert(*it);
else temp.erase(*it);
}
return *temp.begin();
}
};
切片
代码语言:javascript复制class Solution {
public:
int singleNumber(vector<int>& nums) {
set<int>temp;
for(auto & i:nums)
if(temp.find(i)==temp.end())temp.insert(i);
else temp.erase(i);
return *temp.begin();
}
};
方法三:异或
根据0和任何数异或是数本身,数本身异或为0的巧妙之处,可以通过连续异或来找到只出现一次的数,因为两次出现的数异或之后为0,而且异或的顺序不影响。
代码语言:javascript复制class Solution {
public:
int singleNumber(vector<int>& nums) {
int temp=0;
for(vector<int>::iterator it=nums.begin();it!=nums.end();it ){
temp^=*it;
}
return temp;
}
};
切片
代码语言:javascript复制class Solution {
public:
int singleNumber(vector<int>& nums) {
int temp=0;
for(auto & i:nums)
temp^=i;
return temp;
}
};