力扣287 寻找重复数

在这里插入图片描述

   本题使用了抽屉算法,抽屉算法又名鸽巢原理,如果n+1个物体被放进n个盒子,那么至少有一个盒子包含两个或更多的物体。
   比如在这里插入图片描述
有8(1-7)个数字要在这些个抽屉里放,那么这个抽屉里会有一个重复
在这里插入图片描述
   首先,mid=(left+right)/2=4,本来按道理来说,小于等于4的元素个数应该就是4,但是现在发现小于等于4的一共有5个>mid,说明在[0,left-mid]中会出现重复元素。同理,如果小于等于4的元素等于mid,说明重复的元素会出现在[mid+1,right]。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

class Solution {
    public int findDuplicate(int[] nums) {
        int len = nums.length;
        int left = 1;
        int right = len - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;

            int cnt = 0;
            //统计nums中有多少数是小于mid的
            for (int num : nums) {
                if (num <= mid) {
                    cnt += 1;
                }
            }
            //如果个数大于mid,说明重复的数字就在1-mid中间。如果小于mid,说明重复数字在mid-right之间
            if (cnt > mid) {
                // 重复元素位于区间 [left..mid]
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值