zoukankan      html  css  js  c++  java
  • 【LeetCode-查找】寻找重复数

    题目描述

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

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

    说明:

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

    题目描述: https://leetcode-cn.com/problems/find-the-duplicate-number/

    思路

    题目中的要求:

    • 不能更改原数组(假设数组是只读的),说明不能用排序的方法;
    • 只能使用额外的 O(1) 的空间, 说明不能使用哈希表;
    • 时间复杂度小于 O(n2),说明不能用两层循环;

    可以使用二分查找的思想来做。首先介绍一下鸽巢原理:n+1 只鸽子放到 n 个鸽巢里,则肯定有一个鸽巢中的鸽子个数大于 1。则我们设置两个指针 left 和 right,计算 mid = (left+right)/2。统计输入数组 nums 中小于等于 mid 的元素个数 cnt,如果 cnt>mid,则说明 [left, mid] 之间的元素个数超过了 mid,则重复的数字一定在 [left, mid] 之间,否则重复的数字在 [mid+1, right] 之间。循环结束时,left 就是重复的元素。代码如下:
    写法1:

    class Solution {
    public:
        int findDuplicate(vector<int>& nums) {
            int left = 1;
            int right = nums.size()-1;
            while(left<right){
                int mid = left+(right-left)/2;
                int cnt = 0;
                for(int num:nums){
                    if(num<=mid) cnt++;
                }
    
                if(cnt>mid){
                    right = mid; // 因为是循环条件是left<right,所以这里是 right=mid;
                }else{
                    left = mid+1;
                }
            }
            return left;
        }
    };
    

    写法2:

    class Solution {
    public:
        int findDuplicate(vector<int>& nums) {
            int left = 1;
            int right = nums.size()-1;
            while(left<=right){
                int mid = left+(right-left)/2;
                int cnt = 0;
                for(int num:nums){
                    if(num<=mid) cnt++;
                }
    
                if(cnt>mid){
                    right = mid-1;
                }else{
                    left = mid+1;
                }
            }
            return left;
        }
    };
    

    写法 1 和写法 2 的区别在于更改了循环条件和 right 的更新方式,这一点和二分查找是一样的。

    • 时间复杂度:O(nlogn)
    • 空间复杂度:O(1)

    参考

    https://leetcode-cn.com/problems/find-the-duplicate-number/solution/er-fen-fa-si-lu-ji-dai-ma-python-by-liweiwei1419/

  • 相关阅读:
    .NET5微服务示例-Ocelot网关
    .NET5微服务示例-Polly熔断与降级
    .NET5微服务示例-Consul注册中心
    .NET下使用ELK日志中心
    [ 题解 ] [ 数学 ] [ JZOJ5809 ] 数羊
    [ 题解 ] [ 数学 ] 函数 (sequence) (欧拉函数)
    [ 题解 ] [ JZOJ5777 ] 小 x 玩游戏
    更换谷歌浏览器视频输入源
    axios 封装及 API 接口管理
    小程序代码压缩实践
  • 原文地址:https://www.cnblogs.com/flix/p/12968570.html
Copyright © 2011-2022 走看看