问题描述
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之间。这个数组一定有重复的数字,找到这个重复的数字。
这个题目与Linked List Cycle是一样的,nums[0]相当于是链表的头;因为数组中有重复的数字,相当于链表中环的情况(可以理解为本来应该是一条线段的链表,因为一个重复的出现,把尾巴链到了自己身上。)
我们可以同样的用快慢两个指针,当fast和slow相遇了之后,将fast返回头部(不能乱选位置的),然后同样速度前进,再次相遇的时候一定是环开始的地方,也就是重复的元素了。
代码
class Solution {
public:
int findDuplicate(vector<int>& nums) {
if (nums.size() < 2)
return -1;
int slow = nums[0];
int fast = nums[nums[0]];
while (fast != slow){
slow = nums[slow];
fast = nums[nums[fast]];
}
fast = 0;
while (fast != slow){
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
};
时间复杂度:
O(n)
空间复杂度:
O(1)
反思
没能相当链表的方向上来。不过按照题目的要求,可以先排序一波,或者直接比对。