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

题目链接

一个长度是n+1的数组,出现的整数都在1到n之间(包括1和n),已知有一个重复出现的整数。求该整数。

要求:

1.不能更改原数组

2.空间复杂度O(1)

3.时间复杂度小于O(n²)

4.数组中只有一个重复的数字,但它可能不止重复出现1次。


花了点时间才想明白,原来二分法可以这么使用。


当n为奇数,且重复出现的数字为奇数,奇数个数>偶数个数

当n为奇数,且重复出现的数字为偶数,偶数个数>=奇数个数


当n为偶数,且重复出现的数字为奇数,奇数个数>偶数个数

当n为偶数,且重复出现的数字为偶数,偶数个数>奇数个数


总结一下就是:

当奇数个数>偶数个数时,重复出现的数字在奇数里,那么继续从奇数的奇数和奇数的偶数里找。

当偶数个数>=奇数个数时,重复出现的数字在偶数里,那么继续从偶数的奇数和偶数的偶数里找。


什么时候算是找到了呢,

当奇数个数==0,说明偶数里全是重复的数字(对吗,欸,是吗)

当偶数个数==0,说明奇数里全是重复的数字


代码如下:

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int len=nums.size();
        int s1=1,s2=2,d=2,couts1,couts2;//糟糕的命名,s1表示奇,s2表示偶,
        int s_1,s_2;
        while(1)
        {
            couts1=0;
            couts2=0;
            s_1=s1%d;
            s_2=s2%d;
            for(int i=0;i<len;i++)
            {
                if(nums[i]%d==s_1) couts1++;
                if(nums[i]%d==s_2)  couts2++;
            }
            
            if(couts1==0)
            {
                for(int i=0;i<len;i++)
                {
                    if(nums[i]%d==s_2)  return nums[i];
                }
            }
            if(couts2==0)
            {
                for(int i=0;i<len;i++)
                {
                    if(nums[i]%d==s_1)  return nums[i];
                }
            }
            
            if(couts1>couts2)
            {
                s1=s1;
                s2=s1+d;
            }
            else
            {
                s1=s2;
                s2=s2+d;
            }
            d*=2;
        }
    }
};


猜你喜欢

转载自blog.csdn.net/ZRXSLYG/article/details/80629064