题目描述:
在大小为 2N 的数组 A 中有 N+1 个不同的元素,其中有一个元素重复了 N 次。
返回重复了 N 次的那个元素。
示例:
示例1:
输入:[1,2,3,3]
输出:3
示例2:
输入:[2,1,2,5,3,2]
输出:2
示例3:
输入:[5,1,5,2,5,3,5,4]
输出:5
解题思路及代码:
1)直接找
有一半的数相等。那么在排列中若所有相同的数都不相邻,这两个相同数的下标一定相差2,也即只有第一个数和第二个数可能是要找的数,否则就必定存在两个相同的数相邻并相等的情形。
class Solution {
public:
int repeatedNTimes(vector<int>& A) {
int i=0;
if(A[1]==A[3])
return A[1];
for(;i<A.size()-1;i++)
{
if(A[i]==A[i+1])
return A[i];
}
return A[0];
}
};
2)用set解决
将数组中的数据挨个放在set中,记下在每一次插入前的pre_size和插入后的cur_size,因为set中的元素不允许重复,所以若 pre_size==cur_size
,则当前的值即为要找的值。
class Solution {
public:
int repeatedNTimes(vector<int>& A) {
set<int> s;
int i = 0;
for(;i<A.size(); i++){
int pre_size = s.size();
s.insert(A[i]);
int cur_size = s.size();
if(pre_size==cur_size)
break;
}
return A[i];
}
};
3)map
由题目可知,若某个元素重复出现,则要找的就是它。
因此可以用map或者unordered_map完成,在前面博客STL进阶之树形关联容器——map和unordered_map中我详细讲了两者的用法,大家可以点链接直接查看。在这里我提供两种解题思路:
1)完成各个元素出现次数的统计,然后比较若it->second==size()/2
则输出it->first
。这里题目中并没有要求排序,所以用unordered_map就能完成。
class Solution {
public:
int repeatedNTimes(vector<int>& A) {
int s=A.size()/2;
unordered_map <int,int> m;
for(auto e:A)
m[e]++; //将所有数存在map中
for(auto e:m)
{
if(e.second==s) //如果e的个数有s个则输出
return e.first;
}
return 0;
}
};
2)我前面博客讲到map有一个接口pair <iterator,bool> insert(make_pair())
,即插入操作时返回值的second位是bool值,unordered_map 的用法可以参考map。只需要在插入时判断,若bool==false
则输出元素的值。
class Solution {
public:
int repeatedNTimes(vector<int>& A) {
unordered_map <int,int> m;
for(auto &e:A)
{
pair<unordered_map<int,int>::iterator,bool> ret=m.insert(make_pair(e,1));
if(ret.second==false)
return ret.first->first;
}
return 0;
}
};