缺少号码面试问题Redux

时间:2010-12-10 05:54:41

标签: c++ math computer-science complexity-theory

确定1到N范围内缺失值的常见访谈问题已经完成了一千多次。变化包括2个缺失值,最多K个缺失值。

示例问题:范围[1,10](1 2 4 5 7 8 9 10)= {3,6}

以下是各种解决方案的示例:

Easy interview question got harder: given numbers 1..100, find the missing number(s)

我的问题是,看到一个缺失值的简单情况是O(n)复杂性,并且较大案例的复杂性收敛于大于O(nlogn)的大小:

通过说明(mergesort)范围并迭代它来观察缺失的元素,难道只是更容易回答这个问题吗?

此解决方案不应超过 O(nlogn),并且能够解决1到N之外的范围问题,例如10到1000或-100到+100等...

有没有理由相信上述SO链接中的给定解决方案比基于排序的解决方案更适合大量缺失值?

注意:对于这个问题,似乎有许多常见的解决方案,假设只有数论的方法。如果在S / E采访中被问到这样的问题,使用更多的计算机科学/算法方法是不谨慎的,假设该方法与数论解决方案的复杂性相同...... < / p>

更多相关链接:

8 个答案:

答案 0 :(得分:11)

您只是指定时间复杂度,但空间复杂性也很重要。

问题的复杂性可以用N(范围的长度)和K(缺失的元素的数量)来指定。

在你链接的问题中,使用方程的解是空间中的O(K)(或者可能更多?),因为每个未知值需要一个方程。

还有保存点:你可以改变已知元素的列表吗?在许多情况下,这是不可取的,在这种情况下,任何涉及重新排序元素或消耗它们的解决方案必须首先在空间中复制O(N-K)。

我看不到比线性解决方案更快的速度:您需要读取所有已知元素(N-K)并输出所有未知元素(K)。因此,你不能及时比O(N)好。

让我们分解解决方案

  • 销毁,O(N)空间,O(N log N)时间:就地排序
  • 保留,O(K)空间?,O(N log N)时间:方程系统
  • 保留,O(N)空间,O(N)时间:计算排序

就个人而言,虽然我发现等式系统解决方案很聪明,但我可能会使用其中一种排序解决方案。让我们面对现实:它们更容易编码,尤其是计数排序!

就时间而言,在真正的执行中,我认为“计算排序”将击败所有其他解决方案。

注意:计数排序不要求范围为[0, X),任何范围都可以,因为任何有限范围都可以转换为[0, X)形式简单的翻译。

修改

将排序更改为O(N),需要使用所有元素对它们进行排序。

我有时间思考这个问题,我还有另一个解决方案。如上所述,当N(显着)增长时,所需的空间可能会爆炸。但是,如果K很小,那么我们可以使用区间来改变列表的表示形式:

  • {4, 5, 3, 1, 7}

可以表示为

  • [1,1] U [3,5] U [7,7]

在一般情况下,维护一个排序的间隔列表比维护一个排序的元素列表要便宜得多,而且推断丢失的数字也很容易。

时间复杂度很容易:O(N log N),毕竟它基本上是一种插入排序。

当然真正有趣的是没有必要实际存储列表,因此您可以使用流向算法提供它。

另一方面,我很难搞清楚平均空间复杂度。占用的“最终”空间是O(K)(最多K + 1个间隔),但在构造过程中,由于我们不按特定顺序引入元素,因此会有更多的缺失间隔。

最坏的情况很容易:N / 2个间隔(想想奇数和偶数)。然而,我无法弄清楚平均情况。我的直觉告诉我它应该比O(N)更好,但我不是那么信任。

答案 1 :(得分:3)

因为数字来自一个小的有限范围,所以它们可以在线性时间内“排序”。

我们所做的就是初始化一个包含100个布尔值的数组,并为每个输入设置对应于输入中每个数字的布尔值,然后逐步报告未设置的布尔值。

答案 2 :(得分:2)

如果总 N 元素,其中每个数字 x 1&lt; = x&lt; = N 那么我们可以解决这在 O(nlogn)时间复杂度和 O(1)空间复杂度。

  1. 首先使用quicksort或mergesort对数组进行排序。
  2. 扫描已排序的数组,如果先前扫描的数字,a和当前数字之间的差值b等于2(b - a = 2),则缺失的数字为+ 1。这可以扩展到条件(b-a> 2)。
  3. 当N> 1时,时间复杂度为O(nlogn)+ O(n)几乎等于O(nlogn)。 100。

答案 3 :(得分:1)

给定的解决方案在理论上是否优于排序依赖于N和K.虽然您的解决方案具有O(N*log(N))的复杂性,但给定的解决方案是O(N*K)。我认为给定的解决方案(与排序解决方案相同)只需将范围[A, B]转换为[A, B]即可解决任何范围[1, N]

答案 4 :(得分:1)

这个怎么样?

  1. 创建包含所有数字的自己的集合
  2. 从您的集合中删除给定的一组数字(无需排序)
  3. 你的套装中剩下的是缺少的数字。

答案 5 :(得分:0)

如果向前提供了范围,在这种情况下范围是[1,10],您可以使用您的范围和给您的数字执行XOR操作。由于XOR是可交换操作。你将留下{3,6}

(1 2 3 4 5 6 7 8 9 10)异或(1 2 4 5 7 8 9 10)= {3,6}

答案 6 :(得分:0)

我的问题是,随着案件的大致收敛 比O(nlogn)[...]

大的东西

2011年(在您发布此问题之后)Caf发布了a simple answer,该问题解决了O(n)时间和O(k)空间[其中数组大小为{{1 }}]。

重要的是,与其他解决方案不同,Caf的答案没有隐藏的内存要求(使用位数组,向元素中添加数字,将元素与n - k相乘-这些都需要-1空间)。

注意:此处的问题(和原始问题)并未询问该问题的流版本,此处的答案也无法解决该情况。


关于其他答案:我同意,针对该问题提出的许多“解决方案”都具有可疑的复杂性要求,并且如果它们的时间复杂性在某种程度上没有哪一种更好:

  • 计数排序(O(log(n))时间和空间)
  • 比较(堆)排序(O(n)时间,O(n*log(n))空间)

...那么您也可以通过排序解决问题。

但是,我们 可以 获得更好的复杂性(更重要的是,真正更快的解决方案):

答案 7 :(得分:-1)

我已经回答了HERE

您还可以创建大小为for的布尔数组。

true循环中标记现有数组中存在的所有元素for

在另一个false循环中,打印包含O(last_element_in_the_existing_array)的元素的索引,也就是缺少的元素。

时间复杂度:O(array.length)

空间复杂度:(collection) company - (field) client_list - (field) revenue - subcollection1 - subcollection2