美文网首页
寻找重复数

寻找重复数

作者: Houtasu | 来源:发表于2018-08-13 20:07 被阅读0次

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

    示例 1:

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

    示例 2:

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

    说明:

    不能更改原数组(假设数组是只读的)。
    只能使用额外的 O(1) 的空间。
    时间复杂度小于 O(n2) 。
    数组中只有一个重复的数字,但它可能不止重复出现一次。
    解题思路:
    首先,我们人类的思维是从前往后数,每次在前面找有没有重复的,找到就停止了。但是这样时间复杂度是O(n2),因为每一次都需要从头遍历到当前位置。
    然后我想到了使用集合,分别对nums和nums的集合求和再相减,这样就可以找到重复的值了,又因为重复的数字可能不止一个,所以还要除以nums和nums的集合的长度的差值。
    代码如下:

    class Solution:
        def findDuplicate(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            a=set(nums)
            coun=len(nums)-len(a)
            return int((sum(nums)-sum(a))/coun)
    

    代码很简单,跑的也很快,排在第二条柱子上。
    但是,我在写这篇博客时,突然想到python的列表转集合会去掉重复的值,那这个值不就是我们需要的么?还要后面的求和相减相除的那些干什么?还有,python是怎样实现列表转集合的?它是不是每添一个数也要遍历一下,看是不是有重复的?
    我们一直使用着python便利的内置库,内置方法,但有没有思考过这些方法的代码实现是怎么样的?虽然说python本身就运行效率低下,主要是为了使用的方便。
    但这道题指明了时间和空间复杂度要求的,它作为一道中级题,肯定不是考我们python用的熟不熟练,所以我们要思考使用这些python方法的时候,有没有超过这些要求,要从算法层面来解决这道题。
    所以我查找了一下python集合的内部实现,然而并没有百度到相关信息。不过,我在python高级编程这本书中找到了一些信息。里面讲解了字典和集合的具体实现细节,它使用了伪随机探测的散列表来作为字典的底层数据结构,而集合被实现为带有空值的字典。由于使用了散列表结构,所以它并不会通过遍历已有元素来确定是否重复了。
    我们在做这道题时,也可以直接使用nums里的数值来作为存储的地址,比如直接创建一个长度为nums中最大值的数组t = [0]*max(nums),然后用t(n)来存储元素的个数。这就是散列表的基本原理。但是这个最大值可能会大于nums的长度,这样就超出了O(1)的空间限制了。顺便说一下,排在第一的算法是错误的,因为他直接使用nums长度创建t数组,但这样可能导致数组越界。可能测试实例的数量比较少,没有测出来。
    因此,我们是可以使用列表转集合或者使用字典来计数的方法的。由于字典获取元素的平均复杂度为O(1),所以总的复杂度为O(n)。占用空间大小和nums的大小相同。

    相关文章

      网友评论

          本文标题:寻找重复数

          本文链接:https://www.haomeiwen.com/subject/fqxpbftx.html