Given an arraynums containingn + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
-
Youmust not modify the array (assume the array is read only).
-
You must use only constant,O(1) extra space.
-
Your runtime complexity should be less thanO(n2).
-
There is only one duplicate number in the array, but it could be repeated more than once.
这道题要找出特定数组中重复出现的元素,要求空间复杂度O(1),因此不能用HashTable,同时要求时间复杂度低于O(n2),所以也不能用两层循环暴力比对,题目难度为Hard。
思考很久始终没想到合适的办法,查看别人的做法后恍然大悟,由于数组元素的特殊性,可以采用快慢指针的方法解决(能否想到这里是关键!!)。关于快慢指针请查看第141和142题的解释。
数组中元素在1和n之间,因此遍历数组时可以拿当前元素的数值作为下一元素的下标,这样就把数组串联起来形成了一个链表。由于存在重复元素,所以链表中必定存在回环,重复元素就是回环的入口,这就把问题转化成了第142题。看到这里,大家应该不难解决这道题了。具体代码:
class Solution {
public:
int findDuplicate(vector<int>& nums) {
if(nums.size() < 1) return 0;
int fast = 0, slow = 0;
do {
slow = nums[slow];
fast = nums[nums[fast]];
} while(slow != fast);
fast = 0;
do {
slow = nums[slow];
fast = nums[fast];
} while(slow != fast);
return slow;
}
};