一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
方法一:
利用set特性:set作为关联容器,可以用来判断一个值是否存在,set不能包含重复的关键字:
set的insert函数返回一个pair,告诉我们插入操作是否成功:
pair的first成员是一个迭代器,指向具有指定关键字的元素;
pair的second是一个bool值,表示元素是否成功插入,成功true,失败false。
代码如下:
int findRepeatNumber(vector<int>& nums) {
int n = nums.size();
set<int> a;
for(int i = 0;i<n;i++){
auto ret = a.insert(nums[i]);
if(!ret.second){/*若元素插入失败,返回该元素*/
return nums[i];
}
}
return -1;
}
****方法二*****:
注意到数组nums中的数字都在0~n-1范围内。若数组中没有重复的数字,那么当数组排序之后数字i将出现在下标为i的位置。nums[i]=i;由于数组中有重复的数字,有些位置nums[i]≠i。
代码如下:
int findRepeatNumber(vector<int>& nums) {
int n = nums.size();
int temp;
for(int i = 0;i<n;i++){
while(nums[i]!=i){
if(nums[i] == nums[nums[i]]){
return nums[i];
}
//交换nums[i] 和 nums[nums[i]]
temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}
可以看出,在一次交换中,可以将一个nums[temp] = temp;尽管while存在,但是while的判断条件就是nums[i]是否等于i,所以在n次循环中该算法时间复杂度为O(n);空间复杂度为O(1)。