【问题标题】:Time complexity of obtaining the k smallest values overall from n sorted arrays?从n个排序数组中获得k个最小值的时间复杂度?
【发布时间】:2014-01-10 17:16:33
【问题描述】:

我有 n 个数组。这些数组中的每一个都可以是无限长的。 (长度可以是可变的)。所有这 n 个数组都已排序。

现在我想从这 n 个已排序的数组中取出前 k 个最小的元素。

例如 n=5 和 k=10

2 4 6 7 9 

23 45 67 78 99

1 2 6 9 1000 4567 6567 67876

45 56 67 78 89 102 103 104

91 991 9991 99991 

现在答案应该是1 2 4 6 7 9 23 45 56 67

在最坏的情况下是 O(n*k),即 O(n^2),在最好的情况下是 O(k)?

【问题讨论】:

  • 运行时还是空间?那么空间限制呢?
  • @Gumbo 没有空间限制,足够的内存
  • 当您说“最大”时,我认为您的意思是“最小”
  • 一个可以写很多算法来解决这个问题,它们之间会有很多时间复杂度。您是否有特定的想法,或者您是否要求我们给您(可能是最快的)一个?如果您要求我们给您一个,您应该展示您自己想出一个的尝试。
  • @Dukeling 如果你能给我,我要求最好的情况。

标签: algorithm sorting time-complexity


【解决方案1】:

我认为是 O(n + k.log(n))。

首先在每个数组中构建一个最小元素的堆(也存储数组的索引)。构建大小为 n 的堆是 O(n)。然后,重复 k 次:从堆中取出一个元素(即 O(log n)),然后从数组中插入下一个最小的元素,该元素来自于该数组(也是 O(log n))。总的来说,这是 O(n + k.log(n))。

【讨论】:

  • 其实你应该从最大的开始,但是,是的,这是正确的。
  • 取决于您是否相信问题或给出的示例:)
  • +1。这就是答案。我最初在这里误解了您对n 的使用。干得好。
【解决方案2】:

Anonymous 提供的答案在这种情况下是更好的解决方案,因为我们知道各个数组都已排序。

在最坏的情况下,您可以在 O(n log k) 时间内使用堆来完成此操作。它将需要 O(k) 额外空间。

initialize a MAX heap
for each array
    for each item in the array
        if (heap.count < k)
            heap.insert(item)
        else if (item < heap.peek())
        {
            // item is smaller than the largest item on the heap
            // remove the smallest item and replace with this one
            heap.remove_root()
            heap.insert(item)
        }
        else
        {
            break;  // go to next array
            // see remarks below
        }

因为您知道数组最初是排序的,所以您可以包含我展示的最终优化。如果您正在查看的项目不小于堆上已经存在的最大项目,那么您知道当前数组中没有其他项目会更小。所以你可以跳过当前数组的其余部分。

这是为您提供最小的k 项目的算法。如果您想要最大的k 项目,请构建一个MIN 堆并将if (item &lt; heap.peek()) 更改为if (item &gt; heap.peek())。在这种情况下,您可以通过向后遍历数组来获得更好的性能。这将减少堆插入和删除的数量。如果您不向后遍历数组,您将无法使用我展示的优化。

另一种方法是将所有项目连接到一个数组中并使用Quickselect。 QuickSelect 是一种 O(n) 算法。 Empirical evidence 建议在 k &lt; .01*n 时使用堆更快。否则,快速选择会更快。当然,您的里程可能会有所不同,并且必须从多个数组中创建一个数组会增加 Quickselect 的处理和内存开销。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 2016-03-20
    • 2018-01-11
    • 2014-08-06
    • 2018-06-30
    • 2022-11-23
    相关资源
    最近更新 更多