leetcode

287. 寻找重复数

2020-05-26  本文已影响0人  geaus

题目描述

给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
示例:

输入: [1,3,4,2,2]
输出: 2
示例 2:

输入: [3,1,3,4,2]
输出: 3

说明:

不能更改原数组(假设数组是只读的)。
只能使用额外的 O(1) 的空间。
时间复杂度小于 O(n2) 。
数组中只有一个重复的数字,但它可能不止重复出现一次。

解题思路

  1. 二分法
    假定在某一个值i,如果i前面有重复的数那么一定会有cnt(i)>i,这里cnt(i)表示到值i时个元素个数;否则的话重复数字一定>i;这样就可以在i之后查找重复数字。
int findDuplicates(vector<int>& nums){
    int n = nums.size();
    int l=1, r=n-1;
    int ans=-1;

    while(l<=r){
        int mid = (l+r)>>1;
        int cnt=0;
        for(int i=0;i<n;i++){
            cnt += nums[i]<=mid;
        }
        if(cnt<=mid){
            l = mid+1;
        }else{
            ans = mid;
            r = mid-1;
        }
    }

    return ans;
}
  1. floyd环的思路
    设置fast,slow指针,fast指针每次跳两步,slow指针每次跳一步。由于数组中存在重复数字,所以有环。最终两个指针会相遇。这时,将slow指针拨回0下标,然后两个指针每次跳一步,最终相遇的位置即为环的入口(重复数字)。
int findDuplicates(vector<int>& nums){
    int slow=0, fast=0;
    do{
        slow = nums[slow];
        fast = nums[nums[fast]];
    } while(slow!=fast);

    slow = 0;
    while(slow!=fast){
        slow = nums[slow];
        fast = nums[fast];
    }
    return fast;
}
上一篇下一篇

猜你喜欢

热点阅读