287. Find the Duplicate Number

题目:

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:

  1. You must not modify the array (assume the array is read only).
  2. You must use only constant, O(1) extra space.
  3. Your runtime complexity should be less than O(n2).
  4. There is only one duplicate number in the array, but it could be repeated more than once.

思路:

思路1:

使用map保存nums中的元素,通过遍历map可以得到重复的元素。但题目中限制空间复杂度为 O(1) ,所以该方法不可取。

思路2:

暴力查找。使用两层for循环,每次选择一个数字,遍历整个数组查看是否有相同的元素。

思路3:

找环法。若数组中的元素没有重复,则元素可以和下标形成一对一的映射关系。映射函数为:f(n)。n为下标,f(n)为映射到的数。举例说明:数据[2,3,1]的映射关系为0->2->1->3。若数组中有重复的元素,会形成多对一的映射关系。举例说明:数组[1,2,3,1]的映射关系为0->1->2->3->1->2->3->1……可以发现,形成了一个环。

此时,该问题可以转变为:如何在一个链表中,查找环的起始节点。该问题的解决方案参照:http://www.cnblogs.com/sindy/p/6752096.html

代码:

 1 class Solution {
 2 public:
 3     int findDuplicate(vector<int>& nums) {
 4         int fast = 0;
 5         int slow = 0;
 6         do {
 7             slow = nums[slow];
 8             fast = nums[nums[fast]];
 9         } while (slow != fast);
10         fast = 0;
11         while (fast != slow) {
12             fast = nums[fast];
13             slow = nums[slow];
14         }
15         return fast;
16     }
17 };

 

参考:

https://segmentfault.com/a/1190000003817671

原文地址:https://www.cnblogs.com/sindy/p/6776440.html