• [LeetCode] 287. Find the Duplicate Number 解题思路


    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

    Note:

    1. You must not modify the array (assume the array is read only).
    2. You must use only constant, O(1) extra space.
    3. Your runtime complexity should be less than O(n*n).
    4. There is only one duplicate number in the array, but it could be repeated more than once.

    问题:给定一个长度为 n+1 的数组,里面只有 1...n 的数值。可见必然有一个元素的值是重复出现的。假设只有最多只有一个元素的值会重复出现,求出重复的那个值。

    特别要求:

      1. 不能修改原数组

      2. 只用固定空间,空间使用为 O(1)

      3. 时间复杂度要小于 O(n*2)

    基于前两个要求,我首先想到的是两个指针,逐个遍历求解,但是耗时 O(n*n),超时了。在网上看到其他算法,能满足题目要求。

    设 l 为左值, r 为右值, mid 为两者的中间值。值得注意的是,这里的 l, r, mid 均是指元素的值,不是指下标,之所以可以这么做,是因为题目的条件“ n+1 长的数组里面只有 1...n 的数值”。

    • 将数组扫一遍,得到大于等于 l 且 小于等于 mid 的元素个数,即为 num_l_mid。
    • 当 num_l_mid 大于 本应该有的个数,则将重复值定位在 [l, mid] 之间,缩小范围。
    • 当 num_l_mid 小于等于 本应该有的个数,则将重复值定位在 [mid, r] 之间,缩小范围。
    • 重复前面步骤,直到找到重复值。
    int findDuplicate(vector<int>& nums) {
        
        if (nums.size() == 2) {
            return 1;
        }
    
        int l = 1;
        int r = (int)nums.size()-1;
        int mid = (r + l) / 2 ;
        
        int cnt = 0;
        while (l < r) {
            
            int leftLen = mid - l + 1;
            
            for (int i = 0 ; i < nums.size(); i++) {
                if ( l <= nums[i] && nums[i] <= mid) {
                    cnt++;
                }
            }if (l+1 == r) {
                if (cnt > leftLen) {
                    return l;
                }else{
                    return r;
                }
            }
            
            
            if (cnt > leftLen) {
                r = mid;
                mid = (l + mid) / 2;
            }else{
                l = mid;
                mid = (mid + r) / 2;
            }
            
            mid = (r + l) / 2 ;
            cnt = 0;
        }
    
        return 0;
    }
  • 相关阅读:
    php与smarty结合应对表单get的一个小例子
    VC 使用mingw32编译ffmpeg静态库所需文件(二),mingwexsrc.cpp
    wzplayer for delphi
    wzplayer for delphi
    Delphi 调用VC生成的DLL
    VC 使用mingw32编译ffmpeg静态库所需文件(二),mingwexsrc.cpp
    VC使用mingw32编译ffmpeg静态库所需文件(一),ffmpegshim.c
    Delphi和C++数据类型对照表
    VC使用mingw32编译ffmpeg静态库所需文件(一),ffmpegshim.c
    Delphi 调用VC生成的DLL
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5061078.html
Copyright © 2020-2023  润新知