【问题标题】:Printing K smallest number in an array(not kth smallest)在数组中打印 K 个最小的数字(不是第 k 个最小的)
【发布时间】:2018-01-25 16:53:10
【问题描述】:

我正在接受采访。

采访者:你有一个数组,你必须在这个数组中找到 k 个最小的元素,你还必须高效吗?
例如:[2,1,4,5,0] 如果输入为 3,则输出为 0,1,2。

我:我将获取 k 个变量并遍历数组的每个元素,并将所有不同的 k 个最小值存储在 k 个不同的变量中。

采访者:如果你有数百万个数据,你必须找到 10000 个最小的变量怎么办?

ME:是的,获取 10000 个变量实际上是不可能的。因此,我将对数百万数据进行 10,000 次冒泡排序。

采访者:不,好的,下一个问题!

所以,我想知道找到 k 最小的正确方法是什么 数组中的数字,特别是当 k 是一个非常大的数字时?

【问题讨论】:

    标签: arrays algorithm sorting data-structures


    【解决方案1】:

    首先,我们需要找到数组中第 k 个最小的元素。这可以通过任何selection algorithm 完成。

    在计算机科学中,选择算法是一种在列表或数组中找到第 k 个最小数的算法;这样的数字称为 k 阶统计量。

    然后我们需要像快速排序算法一样进行分区操作。分区对数组进行重新排序,以便所有值小于第 k 个最小元素的元素排在它之前,而所有值大于第 k 个最小元素的元素排在它之后。分区的复杂度为O(n)

    选择算法的一个非常简单的实现是Quickselect 算法(包括分区),它类似于快速排序。在平均情况下,算法的复杂度为O(n)

    有更复杂的方法可以在最坏的情况下找到O(n) 中的第 k 个最小元素(k 阶统计量),例如 Median of median algorithm。但我认为 Quickselect 足以回答面试问题。

    【讨论】:

    • 在最坏的情况下也需要 O(n^2)?虽然我对答案很满意。就像每次枢轴都是要检测的所有值中最大的一样(快速选择)?我只是想知道我的想法是否正确。
    • @AbhijeetKumar 是的,Quickselect 的最坏情况时间复杂度是O(n^2),但是如果有一个很好的枢轴选择策略,最坏情况很难得到,无论如何,你可以将快速排序部分替换为介绍部分,这会给你O(n*log(n)) 复杂性。
    • 好的,你能告诉我一件事,比如如果我需要在数组中搜索一些未排序的元素,那么应用二进制搜索需要对其进行排序,但是如果我用一个好的实现快速选择那么枢轴选择策略会是一个不错的选择吗?
    • @AbhijeetKumar 如果你想搜索一个元素(不是第 k 个)你不需要所有这些东西,一个简单的线性搜索会更好。
    【解决方案2】:

    这可以使用MinHeap 解决。 MinHeap 以父节点的值始终小于其子节点的方式存储节点。要从 MinHeap 中提取最小值,只需提取根的值。

    从数组构建 MinHeap 需要 O(n) 时间复杂度。 (n 是值的数量)

    提取根节点后,要找出下一个最小值,我们必须将其替换为堆的数组表示中的最后一个值,并将该堆minHeapify。 这需要 O(logn) 时间复杂度。

    假设 N 是数组中值的数量,并要求您找到 K 个最小值。然后,通过使用这种方法,将需要 O(N + K log(N)) 时间复杂度。例如,如果 N 为 106,K 为 103,则大约需要 106 + 2*104 次迭代,大约需要不到 1 秒的时间。虽然代码写起来相当复杂。

    【讨论】:

      猜你喜欢
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      • 2019-08-13
      • 2022-11-19
      • 2013-01-04
      相关资源
      最近更新 更多