题目描述:
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.
题目大意:给一个含n+1个整数的数组(整数范围是1-n),证明至少有一个数是重复的(假设只有一个整数是重复的)
思路:题目要求不能修改数组(不能排序),O(1)空间复杂度(不能哈希),O(n^2)时间复杂度(不能嵌套循环比对)。然后不会做。。。
看了一下网上的算法,原来可以用图论的寻环算法。大概解释一下这个算法:利用快慢指针与环的性质可以得到:快指针走2步,慢指针走1步,直到相遇,接下来慢指针走1步,一个新指针从起点开始走1步,直到相遇,相遇点即是环的起点(重复的数字)。寻环算法详解
怎么把算法应用到题目上呢,如果数组中有重复的整数,说明一定数组中一定有两个不同的下标1,2指向相同的整数,假设一个指针一直向前走(寻找初始下标指向的数字,再以这个数字作为下标寻找下一个数字),那么走到下标1,经过一定步数,一定会走到下标2,那么再经过一定步数会再次回到这个相同的数字,所以就是说,这个重复的数字就是环的起点,就可以利用寻环算法了。
c++代码:
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int fast = 0, slow = 0;
do
{
slow = nums[slow];
fast = nums[nums[fast]];
} while (slow != fast);
int ans = 0;
while (ans != slow)
{
slow = nums[slow];
ans = nums[ans];
}
return ans;
}
};