leetcode每日一题---寻找重复数

  1. 题目描述
  2. 思路和题解
  3. 代码
  4. 闲话

题目描述

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

实例

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

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

说明

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

题解

首先我对这个题目的感受是很特殊,真的很特殊。你可以读出来,最后一句话降低了难度。他有很多的限制在说明里面。(千万不要觉得这不好,其实这可以提高代码能力
我担心有些读者不理解说明的含义,我先对其进行自己的解读:

  1. 第一条说的很清楚了,不能改,只能读。
  2. O(1)这个就表示你只能定义变量,不能利用数组,哈希表等。
  3. 这句就是告诉你不要去想暴力求解,他的时间复杂度很高。
  4. 字面意思,你可以明白的。

他的题目中有句话让我觉得二分查找可能会好点(其数字都在 1 到 n 之间(包括 1 和 n))他的题目已经给你限制了数据的大小,如果没有的话,二分查找就不能使用。

那么我们开始思路的探讨
因为此题他定位了数组数据的范围,所以我们可以进行二分查找定位到那个重复的数上。
首先,我们确定中值是什么?left=1,right=n-1(n指的是数组数据的长度)
mid=(left+right)/2,这就是中值。
接下来,我们确定中值之后就是要找某个数重复的次数。怎么确定呢?先举个栗子。 [1,3,4,2,2] 这样的一个数组,他的中值是2.5,我要统计比mid这个数大的个数和小的个数,很明显比mid小的数有3个,个数严格大于了他的mid,所以重复的数等于[1,2.5]区间的一个数,这样一步一步缩减,最后得出那个重复的数.
如果还不理解,那么请看下一个栗子

[2, 4, 5, 2, 3, 1, 6, 7],在这个数组中mid是4,接下来统计大于他的数和小于等于他的数的个数,分别是3个和5个,那么你就知道了重复的数在[1,3]区间里,
接下来继续,他的mid是2,重复操作,小于等于mid的数有3个严格大于mid,
接下来的mid就是1,但是小于等于他的数不能严格大于所以,以此条件,退出循环.
那么就找到了重复的数字2.

如果你懂了,你可以自己写,或者看看我的代码.

代码

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int n=nums.size();
        int l=1,r=n-1,ans=-1;
        while(l<=r)
        {
            int mid=(l+r)/2;
            int cnt=0;
            //cout<
            for(int i=0;i<n;i++)
            {
                cnt=cnt+(nums[i]<=mid);
            }
            if(cnt<=mid)
            l=mid+1;
            else {
                r=mid-1;
                ans=mid;
            }
            
        }
        return ans;
    }
};

我想我已经将清楚了,所以我就不做注释了.

闲话

最近事情挺多的,论文挺多的.大心的论文纯编.哈哈哈哈!!!接下来我要好好学习数据结构和英语!!
我想说明一下:我是一名大一的学生,如果我的题解有些地方,不通,或者不对,请大家指出,即使我是小菜鸡但是我还是很爱学习的.谢谢大家!!

你们好!我是大一小菜鸡,又菜瘾还大.

你可能感兴趣的:(数据结构,算法,leetcode,cpp,二分法)