zoukankan      html  css  js  c++  java
  • leetcode

    链接:https://leetcode.com/problems/find-the-duplicate-number/

    两种解法:

    1)利用二分+鸽巢原理

    其实就是使用二分搜索来枚举重复数字的范围;根据鸽巢原理,如果数组中<=1/2n的数字超过了1/2n,则说明1~1/2n中有重复的数字,因此我们可以根据该原理来枚举重复数字所在的范围,具体实现代码如下:

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

    上述算法的时间复杂度是O(nlogn)

    2)类似链表找环的起始节点(映射找环法)

    首先来看一下具体的一个例子,数组元素为2,1,3,将数组下标和元素构成一个映射,即0->2, 1->1, 2->3,我们将该映射看成是一个函数f(n),其中n是元素下标,f(n)是该下标对应的元素;如果我们以0为下标,根据f(n)计算出一个值,再以这个值为下标,则可以得到类似链表的一串数字,0->2->3

    如果数组中有重复的数字,则在上述串会出现重复,例如数组元素为2,1,3,1,则进行顺序映射过程中,有0->2->3->1->1->1.....,因为我们可以借鉴类似链表找环的方式,来查找重复的数字,并且重复的数字就是环的起始位置

    具体代码如下:

    class Solution
    {
    public:
        int findDuplicate(vector<int>& nums)
        {
            int slow = 0;
            int fast = 0;
            do
            {
                slow = nums[slow];
                fast = nums[nums[fast]];
    
            }while(slow != fast);
    
            int find = 0;
            while(find != slow)
            {
                find = nums[find];
                slow = nums[slow];
            }
            return find;
        }
    };

    上述算法的时间复杂度是O(n),可以参加https://segmentfault.com/a/1190000003817671

  • 相关阅读:
    由剑指offer引发的思考——对象中虚函数指针的大小
    lambda表达式在python和c++中的异同
    并发编程(9)线程池---高级线程管理
    并发编程(8)并发算法代码设计
    并发编程(6)基于锁的并发数据结构设计
    并发编程(4)同步并发操作
    并发编程(3)线程间共享数据
    并发编程(2)线程管理
    并发编程(1)简介
    C#中string 和String
  • 原文地址:https://www.cnblogs.com/shirley-ict/p/5487571.html
Copyright © 2011-2022 走看看