美文网首页leetcode
287. 寻找重复数

287. 寻找重复数

作者: geaus | 来源:发表于2020-05-26 19:46 被阅读0次

    题目描述

    给定一个包含 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;
    }
    

    相关文章

      网友评论

        本文标题:287. 寻找重复数

        本文链接:https://www.haomeiwen.com/subject/jeovahtx.html