【问题标题】:Determining the missing number with duplicates in the list确定列表中具有重复项的缺失数字
【发布时间】:2018-12-22 17:33:39
【问题描述】:

我有一个列表l = [3,1,2,5,3]。我的目标是在 O(n) 时间内找到 repeated 的数字,这里是 3,还有 missing 的数字是 4。最后,输出应该是[3, 4]

我尝试使用字典查找重复的数字,但再次查找丢失的数字我正在使用另一个循环,这会导致 O(n^2) 时间复杂度。

谁能告诉如何在 O(n) 时间复杂度中找到答案?

【问题讨论】:

  • 另一个循环不一定会使其成为 O(n^2),如果两个循环按顺序运行则不会。因此,一个循环遍历l 以收集计数,然后另一个循环遍历从 1 到 5 的范围以确定丢失的数字和重复的数字,这将使两个连续循环相加为 O(2n),即 O (n)。
  • 您的算法是否可以访问范围的大小,例如开始和结束编号?
  • 没有。每个输入的列表都可以变化。
  • 所以在初始循环中,还要确定边界、最小值和最大值,或者分别收集它们(实际上无论如何都会更快)。
  • 是的。搞定流程

标签: python algorithm time-complexity


【解决方案1】:

如果你嵌套你的循环,你只会得到一个 O(n^2) 的解决方案。 O(n) 的多个 sequential 循环(因此下一个循环在前一个循环完成后运行)加起来是一个 O(n) 的最终解决方案,您可以根据需要使用任意数量的解决方案。

如果您的输入不包括开始和结束数字,并且您只知道它们将是一个正整数序列,其中缺少一个数字中间某处,则解决方案是首先数数并记录最小和最大数字。然后从最小值循环到最大值,并包含任何缺失或计数为 2 的数字。使用字典进行计数,这样您也将知道缺少哪些数字:

def missing_or_doubled(inputlist):
    counts = {}
    for n in inputlist:  # O(n) loop
        counts[n] = counts.get(n, 0) + 1
    start, end = min(counts), max(counts)  # two sequential O(n) loops
    # final O(n) loop to find missing number and number that appears twice
    return [i for i in range(start, end + 1) if counts.get(i) in {2, None}]

这是 4 个不同的 O(n) 循环,都是顺序的。您也可以在for n in inputlist 循环内确定startend,但这会更慢; min()max() 函数是用 C 实现的,它们较低的常量成本将击败任何用纯 Python 实现的尝试。

演示:

>>> missing_or_doubled([3, 1, 2, 5, 3])
[3, 4]
>>> missing_or_doubled([14, 19, 17, 13, 12, 10, 16, 17, 18, 22, 11, 15, 20])
[17, 21]

如果您事先知道开始或结束编号(因为它作为参数传递给您的代码,或者问题描述明确说明了开始或结束编号是什么),那么只需替换 @987654328 @ 或 max(counts) 分配该信息。例如,如果起始编号始终应为1,则只需使用range(1, end + 1)

【讨论】:

  • [2,2] 输入失败。该算法应返回 [2,1]
  • 你没有指定算法应该如何处理如果“没有数字丢失”的情况(我想说[2,2]的输入没有数字丢失),所以你不能责怪答案没有处理那个案子。
  • @merkle:这意味着必须有一个已知的起点。我的回答清楚地符合上下文:如果您的输入不包括开始和结束数字,并且您只知道它们将是一个正整数序列,而中间某处缺少一个数字。因此,不要使用min(counts) 来确定@​​987654333@,而是使用start = 1
  • @merkle:这就是为什么我特别问你是否知道更多关于开始和结束数字的信息。你对那个问题的回答是模棱两可的,所以我解释说缺少开始和结束值,并假设它们是正整数。
  • 很抱歉没有给出明确的解释。非常感谢@Martjin 的帮助。下次我会说清楚的。
猜你喜欢
  • 2021-08-22
  • 1970-01-01
  • 2015-02-25
  • 2022-11-30
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 2021-04-09
  • 1970-01-01
相关资源
最近更新 更多