Given an array nums containing n + 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.
Example 1:
Input: [1,3,4,2,2] Output: 2
Example 2:
Input: [3,1,3,4,2] Output: 3
Note:
- You must 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 than O(n2).
- There is only one duplicate number in the array, but it could be repeated more than once.
题目设定的问题是N+1个元素都在[1,n]这个范围内。这样我们可以用那个类似于 ‘缺失的第一个正数’ 这种解法来做,但是题意限制了我们不能修改原数组,我们只能另寻他法。也就是本编题解讲的方法,将这个题目给的特殊的数组当作一个链表来看,数组的下标就是指向元素的指针,把数组的元素也看作指针。如0是指针,指向nums[0],而nums[0]也是指针,指向nums[nums[0]].
这样我们就可以有这样的操作
int point = 0;
while(true){
point = nums[point]; // 等同于 next = next->next;
}
链表中的环
假设有这样一个样例:[1,2,3,4,5,6,7,8,9,5]。如果我们按照上面的循环下去就会得到这样一个路径: 1 2 3 4 5 [6 7 8 9] [6 7 8 9] [6 7 8 9] . . .这样就有了一个环,也就是6 7 8 9。point会一直在环中循环的前进。
这时我们设置两个一快(fast)一慢(slow)两个指针,一个每次走两步,一个每次走一步,这样让他们一直走下去,直到他们在重复的序列中相遇,

1 class Solution {
2 public:
3 int findDuplicate(vector<int>& a) {
4 int slow = 0;
5 int fast = 0;
6 while(true) {
7 fast = a[a[fast]];
8 //fast = fast->next->next;
9 slow = a[slow];
10 if(fast==slow) break;
11 }
12 fast = 0;
13 while(true) {
14 fast = a[fast];
15 slow = a[slow];
16 if(fast==slow) return fast;
17 }
18 return -1;
19 }
20 };
55链表中环的入口结点
来源:https://www.cnblogs.com/zle1992/p/12584905.html