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.
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.
分析:如果可以用extra space,那么直接用hashset就可以达到O(n)的复杂度,但是这里不能用额外空间;如果duplicate number只出现两次,那么可以通过求和,来减去标准和来求出duplicate的元素,但是这里duplicate的number可能出现N次,所以不能这么做。解法的思路是类似于linkedlist找环并求出环开始的位置,这里我们用快慢指针的方法,每次走的方法是从index = 0开始,走到index = nums[0]的位置,这样依次向后递推。每次快指针走两次,慢指针走一次直到相遇,相遇后,用一个pointer指针从头开始,slow从相遇点开始,各走一步直到相遇,相遇的index即为duplicate的数字。
public int findDuplicate(int[] nums) {
if (nums.length == 0) return -1;
int slow = 0, fast = 0;
while (slow != nums[fast]) {
slow = nums[slow];
fast = nums[nums[fast]];
}
slow = nums[slow];
int pointer = 0;
while (slow != pointer) {
pointer = nums[pointer];
slow = nums[slow];
}
return slow;
}