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

来源:互联网 发布:香港域名注册處 编辑:程序博客网 时间:2024/05/16 09:54

题目:

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.

题目大意:

  • 给定一个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,两个指针同速而行,最后交于同一节点,这个节点就是答案。

0 0
原创粉丝点击