【问题标题】:Fastest way to return duplicate element in list and also find missing element in list?返回列表中重复元素并在列表中找到缺失元素的最快方法?
【发布时间】:2015-10-10 00:52:59
【问题描述】:

所以我的代码如下所示。输入是一个列表,其中只有一个重复项和一个缺失项。答案是一个包含两个长元素的列表,第一个是列表中的重复元素,第二个是列表中从 1 到 n 范围内的缺失元素。 示例 =[1,4,2,5,1] 答案=[1,3] 下面的代码有效。

我错了,复杂性是 O(n),有没有更快的方法在 Python 中实现这一点? 另外,有什么方法可以在不使用额外空间的情况下做到这一点。

注意:元素的数量级可能为 10^5 或更大

    n = max(A)
    answer = []
    seen = set()
    for i in A:
        if i in seen:
            answer.append(i)
        else:
            seen.add(i)

    for i in xrange(1,n):
        if i not in A:
            answer.append(i)
    print ans

【问题讨论】:

  • 这更适合代码审查。
  • 优化后的代码可能和他贴的完全不一样,所以……
  • 顺便说一句,你没看错:你的代码是 O(n)。它的问题是,正如你所注意到的,它也需要 O(n) 空间复杂度
  • 这个问题可能适合Code Review,只要 (a) 您的代码按预期工作,(b) 您的代码是真实代码,而不是示例代码,并且 (c) 您的代码包含在问题的正文中。如果您希望通过同行评审来改进代码的各个方面,请将其发布在 Code Review 上。
  • (@TigerhawkT3:不,那些人敏感的。)假设你可以做得更快:你会有很多元素没有检查。假设您有两个,并尝试证明没有这些您可能无法找到答案。

标签: python algorithm performance list


【解决方案1】:

你确实是正确的,这个算法的复杂度是 O(n),这是你能达到的最好的。完成重复值后,您可以尝试通过中止搜索来优化它。但最坏的情况是,您的副本位于列表的最后,您仍然需要完全遍历它。

使用散列(您使用集合)是一个很好的解决方案。还有很多其他方法,例如使用Counters。但这不会改变算法的渐近复杂度。

作为@Emisor 的建议,您可以利用您拥有一个包含 1 个重复值和 1 个缺失值的列表的信息。您可能知道,如果您有一个没有重复值且没有缺失值的列表,则将列表中的所有元素相加将得到1+2+3+..+n,它可以重写为数学等价物(n*n+1)/2

当您发现重复值时,您可以计算缺失值,而无需执行:

for i in xrange(1,n):
    if i not in A:
        answer.append(i)

因为如果所有值都存在,您知道总和:total = (n*n+1)/2) = 15,并且您知道哪个值是重复的。通过对数组A = [1,4,2,5,1] 求和,即13 并删除重复值1,得到12

计算出的总数并从中减去计算出的12,得到3

这一切都可以写在一行中:

(((len(A)+1)*(len(A)+2))/2)-sum(A)-duplicate

【讨论】:

    【解决方案2】:

    轻微优化(我认为)

    def lalala2(A):
        _max = 0
        _sum = 0
        seen = set()
        duplicate = None
        for i in A:
            _sum += i
            if _max < i:
                _max = i
            if i in seen:
                duplicate = i
            elif duplicate is None:
                seen.add(i)
    
        missing = -_sum + duplicate + (_max*(_max + 1)/2) # This last term means the sum of every number from 1 to N 
        return [duplicate , missing]
    

    看起来有点丑,我自己做 sum() 和 max() 之类的东西,而不是依赖 Python 的工具。但是通过这种方式,我们只检查每个元素一次。此外,一旦找到重复项,它就会停止向集合中添加东西,因为一旦知道最大值,它就可以从中计算缺失的元素

    【讨论】:

      猜你喜欢
      • 2019-09-06
      • 2021-01-01
      • 2020-02-16
      • 1970-01-01
      • 2018-11-05
      • 2016-01-11
      • 2011-06-01
      • 1970-01-01
      • 2020-12-27
      相关资源
      最近更新 更多