您的位置:首页 > 其它

LeetCode题解(Week 1):287. Find the Duplicate Number

2017-02-25 00:41 459 查看

题目:

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的整数

显然,这个数组中包含重复的数字

假设重复的数字只有1个,但重复的次数不定,请找出这个重复的数字

必须在O(n^2)的时间复杂度以及O(1)的空间复杂度下完成

不能修改原数组的内容

题解1(O(n^2))

class Solution {
public:
int findDuplicate(vector<int>& nums)
{
int n = nums.size();
for(int i=0 ;i < n; i++)
{
for(int j = i+1 ;j <n;j++)
{
if(nums[i]==nums[j])
return nums[i];
}
}
}
};


解题思路1:

这是一种很直接的思路。将数组中的元素两两对比,一旦发现有相等的元素,就把这个相等的元素输出出来。但这种解法的时间复杂度为O(N^2),称不上是一种好的方法。

题解2(O(n))

Solution中,我看到了时间复杂度为O(n)的思路,值得学习。

int findDuplicate3(vector<int>& nums)
{
if (nums.size() > 1)
{
int slow = nums[0];
int fast = nums[nums[0]];
while (slow != fast)
{
slow = nums[slow];
fast = nums[nums[fast]];
}

fast = 0;
while (fast != slow)
{
fast = nums[fast];
slow = nums[slow];
}
return slow;
}
return -1;
}


题解2思路

这个解法的关键在于将数组看成是一个静态的链表。数组中的元素代表链表下一个元素的下标(也就是next)。由于存在n+1个1到n的整数,有一个重复的数字,这就说明了链表中必然成环。

例如给定数组[2,3,3,1],元素的遍历过程是2->3->1->3->1->3,说明了有两个next(1和2)同时指向3,意味着3为重复数字。

至于怎么找到这个两个节点同时指向一个节点,随后成环的情况,可以用快慢指针的方法来解决:先定义一个每次走两步的快指针,再定义一个每次走一步的慢指针,使得慢指针追上快指针。这个时候,再让将快指针拨回0,两个指针同速而行,最后交于同一节点,这个节点就是答案。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode