[LeetCode] 287. Find the Duplicate Number(Floyd判圈算法)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] 287. Find the Duplicate Number(Floyd判圈算法)相关的知识,希望对你有一定的参考价值。

传送门

Description

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之间,证明至少存在一个重复的数。假设仅有一个重复的数,找出它。

要求:

  • 假设数组仅为可读,不允许改变数组
  • 空间复杂度为O(1),时间复杂度要求小于O(n2)

题解:由于不允许改变数组,因此不能将数组排序,又因为额外的空间仅允许O(1),因此,不考虑hash。复杂度不能为O(n2),所以不能暴力求解。

方法一:为了降低复杂度,我们可以考虑二分,将复杂度降低为O(nlogn),每次二分,然后遍历数组,查看小于等于mid的数,如果个数小于等于mid,则证明重复的数小于等于mid,反之在[mid + 1,right]的区间。

方法二:此种方法利用floyd判圈算法的原理来求解,具体可以查看这里:click here

 


class Solution {
public:
    //9ms
    int findDuplicate(vector<int>& nums) {
        if (nums.size() > 1){
            int slow = nums[0],fast = nums[nums[0]];
            while (slow != fast){
                slow = nums[slow];
                fast = nums[nums[fast]];
            }
            fast = 0;
            while (slow != fast){
                slow = nums[slow];
                fast = nums[fast];
            }
            return slow;
        }
        return -1;
    }

    //9ms
    int findDuplicate(vector<int>& nums) {
        int left = 1,right = nums.size() - 1;
        while (left < right - 1){
            int mid = left + ((right - left) >> 1);
            int cnt = 0;
            for (auto val : nums){
                if (val <= mid) cnt++;
            }
            if (cnt <= mid) left = mid;
            else    right = mid;
        }
        return left;
    }
};

以上是关于[LeetCode] 287. Find the Duplicate Number(Floyd判圈算法)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 287. Find the Duplicate Number(找重复数字)

[LeetCode] 287. Find the Duplicate Number

LeetCode 287. Find the Duplicate Number

<LeetCode OJ> 287. Find the Duplicate Number

[LeetCode] 287. Find the Duplicate Number 寻找重复数

LeetCode 287. Find the Duplicate Number (找到重复的数字)