1. 不修改原数组,使用额外的空间
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n = nums.size();
vector<int> hash(n, -1);
for(int i = 0; i < n; i++){
if(hash[nums[i]] != -1) return nums[i];
hash[nums[i]] = nums[i];
}
return -1;
}
};
2. 修改原数组,不使用额外的空间
示例1
示例2
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n = nums.size();
for(int i = 0; i < n; i++){
while(nums[i] - 1 != i){
int val = nums[i];
if (i != val - 1 && nums[i] == nums[val - 1]) return nums[i];
swap(nums[i], nums[val - 1]); // 值为val的数应该放到下标为val - 1的地方
}
}
return -1;
}
};
3 不修改原数组,不使用额外的空间
快慢指针思想,fast 和 slow 是指针,nums[slow] 表示取指针对应的元素,注意 nums 数组中的数字都是在 1 到 n 之间的(在数组中进行游走不会越界),因为有重复数字的出现,所以这个游走必然是成环的,环的入口就是重复的元素
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int slow = 0;
int fast = 0;
do {
fast = nums[nums[fast]];
slow = nums[slow];
} while (nums[slow] != nums[fast]);
int ans = 0;
while (nums[ans] != nums[slow]) {
ans = nums[ans];
slow = nums[slow];
}
return nums[ans];
}
};