0
点赞
收藏
分享

微信扫一扫

力扣第287题“寻找重复数”的解题思路

司马吹风 2022-03-14 阅读 36

参考代码:

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;
            for (int num : nums) {
                if (num <= mid) {
                    cnt += 1;
                }
            }
            if (cnt > mid) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
}

大致思路:二分法。

先猜一个数(有效范围 [left..right] 里位于中间的数 mid),然后统计原始数组中 小于等于 mid 的元素的个数 cnt:

如果 cnt 严格大于 mid。根据抽屉原理,重复元素就在区间 [left..mid] 里;
否则,重复元素就在区间 [mid + 1..right] 里。

具体实现:

int left = 1;
int right = len - 1;

确定最大的一个区间[left,right]即[1,n]

然后找到最中间的一个值,注意将区间一分为二后还要加上区间的下限,这样才是区间的中间的数。遍历mid左边的数,统计小于等于mid的个数

 if (cnt > mid) {
                right = mid;//重复元素位于区间 [left..mid]
            } else {
                left = mid + 1;//else 搜索的区间就是 if 的反面区间 [mid + 1..right]
            }

小于等于 4 的个数如果严格大于 4 个,此时重复元素一定出现在 [1..4] 区间里.

循环到最后会是left=right,也就是那个重复的数。

举报

相关推荐

0 条评论