题目描述:给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
eg:
示例 1:
输入: [1,3,4,2,2]
输出: 2
示例 2:
输入: [3,1,3,4,2]
输出: 3思路描述:最简单的方法就是先排序再遍历
class Solution {
public:
int findDuplicate(vector<int>& nums) {
sort(nums.begin(), nums.end());
for(int i = 1; i < nums.size(); i ++){
if(nums[i] == nums[i - 1])
return nums[i];
}
return 0;
}
};然后还可以使用面试题03中的策略,但是还是会对数组进行修改
class Solution {
public:
int findDuplicate(vector<int>& nums) {
for(int i = 0; i < nums.size(); i ++){
while(i != nums[i]){
if(nums[i] == nums[nums[i]])
return nums[i];
swap(nums[i], nums[nums[i]]);
}
}
return -1;
}
};弗洛伊德龟兔赛跑算法:
如果我们对 nums 进行这样的解释,即对于每对索引
$i$ 和值$v_i$ 而言,“下一个”$v_j$ 位于索引$v_i$ 处,我们可以将此问题减少到循环检测。首先,我们可以很容易地证明问题的约束意味着必须存在一个循环。因为
$nums$ 中的每个数字在 1 和 n之间,所以它必须指向存在的索引,此外,由于 0 不能作为 nums中的值出现,nums[0] 不能作为循环的一部分。
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int tortoise = nums[0];
int hare = nums[0];
do {
tortoise = nums[tortoise];
hare = nums[nums[hare]];
} while (tortoise != hare);
// Find the "entrance" to the cycle.
int ptr1 = nums[0];
int ptr2 = tortoise;
while (ptr1 != ptr2) {
ptr1 = nums[ptr1];
ptr2 = nums[ptr2];
}
return ptr1;
}
};