【问题标题】:Merge k sorted arrays of size n in O(nk) time complexity在 O(nk) 时间复杂度内合并 k 个大小为 n 的排序数组
【发布时间】:2016-01-13 07:34:17
【问题描述】:

最近在一次采访中我被问到这个问题:

以最小的时间复杂度将 k 个已排序的数组合并为一个大小为 n 的数组,每个数组具有 n 个元素。k。*

我给出了一个解决方案,使用大小为 k 的 minheap 来找到 k 个列表的顶部元素中的最小值。

这样时间复杂度会降到 - O(nklogk)。

但他并不相信。他想要一个时间复杂度为 O(nk) 的解决方案。

我在互联网上搜索过,但找不到解决方案。

【问题讨论】:

  • 对于comparison sort,这是不可能的。否则,您可以使用计数排序或桶排序(例如)。
  • @shx2 我接受了你的回答,但是由于面试官问了我这个问题,我只是在这里等待更多的答案/cmets。
  • 不确定它是否仍然相关,我想面试官可能会混淆n。他很可能认为n 是所有k 列表中的元素数;在描述问题时,他提到n 是每个列表的长度。

标签: algorithm sorting data-structures merge heap


【解决方案1】:

他错了,你是对的。或者这可能是一个诡计问题。

如果存在这样的解决方案,您可以在 O(K) 中对任何大小为 K 的数组进行排序,这被证明是不可能的。

方法如下:您只需将大小为 K 的数组划分为 K 个单例数组,然后应用您的魔法函数。

当然,单例数组都是单独排序的。复杂性:O(K) 用于构建单例数组,O(K*1) 用于合并(根据我们反驳的假设)。

【讨论】:

  • 他也给了我一个提示。他说如果所有数组都是可变长度的,那么在 k 个数组中有 N 个元素。他说在那种情况下时间复杂度将是 O(Nlogk)。他进一步说,由于您可以放松所有数组的大小为 n,您可以从中获得一些好处,并通过较少的比较来解决问题
  • @ArpitAggarwal,我不确定你在说什么,但如果元素的总数是 N*K,那么最好的复杂度是 O(NKlogK),而不是 O(NK)。如果是N,最好的复杂度是O(NlogK),而不是O(N)。重新放松,他错了,正如我的回答所证明的那样。
【解决方案2】:

虽然你说的对,任何比较排序的下限都是 n*log(n) [其中 n 是数组的大小],但有些排序算法可能需要更少的时间。

由于您有 k 个排序列表,因此很容易找到您想要在最后获得的列表的最小值(称为 m)和最大值(称为 M)。现在您知道需要排序的每个元素都在 m 和 M 之间。因此您可以使用需要线性时间的计数排序。 [https://en.wikipedia.org/wiki/Counting_sort]

因此,需要 O(k) 才能找到 m 和 M,然后 O(n*k) 才能对数组进行排序。所以整个算法需要O(nk)

【讨论】:

  • 不是 O(nk),而是 O(nk*(M-m))。对于像[ [0], [9999999999999] ] 这样的非常短的输入,它的效果如何?问题中没有任何内容表明您可以对这些值做出任何假设。此外,它仅在值是整数时才有效。问题没有说明这一点。如果它们是花车呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 2017-11-12
  • 1970-01-01
相关资源
最近更新 更多