当前位置: 首页 > 知识库问答 >
问题:

从大型未排序数组中检索K个最大元素的最佳方法?

郭知
2023-03-14

我最近在一次面试中进行了一次编码测试。我被告知:

有一个100万int的大型未排序数组。用户想要检索K个最大的元素。您将实现什么算法?

在这期间,有人强烈暗示我需要对数组进行排序。

所以,如果性能真的很重要,我建议使用内置的ort()自定义实现。然后我被告知,使用Collection或数组来存储k最大和for循环,可以实现大约O(N),事后看来,我认为这是O(N*k),因为每次迭代都需要与K大小的数组进行比较以找到要替换的最小元素,而对数组进行排序的需要将导致代码至少为O(N log N)

然后我查看了SO上的这个链接,它建议K数字的优先级队列,每次找到较大的元素时都会删除最小的数字,这也会给出O(N log N)。编写一个程序,从10亿数组中找出100个最大的数字

for循环方法不好吗?我应该如何证明使用for循环或优先队列/排序方法的优缺点?我在想,如果数组已经排序,它可以通过不需要再次遍历整个数组来帮助,即如果在排序的数组上调用其他一些检索方法,它应该是恒定的时间。在运行实际代码时是否有一些我在理论化伪代码时没有考虑的性能因素?

共有3个答案

葛承德
2023-03-14

这里有一个想法。我将考虑使用最大大小(2147483647)创建数组(int),因为它是int的最大值(2147483647)。然后,对于我从原始数组中得到的每个数字,只需在我创建的空数组中放入相同的索引(与数字)1。

所以在最后,对于每个,我将有类似[1,000,2,0,3](我创建的数组)的东西,它们代表数字[0, 2, 2, 4, 4, 4](初始数组)。

因此,要找到K最大的元素,您可以在创建的数组上为向后创建,并从K倒数到0每次当你有不同的元素时,然后是0。如果您有例如2,则必须将此数字计数2次。

这种方法的局限性在于,由于数组的性质,它仅适用于整数。。。

此外,int在java中的表示形式为-2147483648到2147483647,这意味着在需要创建的数组中只能放置正数。

注意:如果您知道int的最大值,则可以使用该最大值减小创建的数组大小。例如,如果最大int为1000,那么您需要创建的数组的大小为1000,那么该算法应该执行得非常快。

骆英纵
2023-03-14

我认为你误解了你需要整理的东西。

您需要对K大小的列表进行排序,而不需要对原始的N大小的输入数组进行排序。这样,时间复杂度将为O(N*log(K))。

要求指出,N非常大,但K小得多,因此O(N*log(K))也比O(N*log(K))小。

对于K大小的列表,您可以看看是否有具有固定容量和自定义比较器的PriorityQueue实现,它使用PriorityQueue和一些附加逻辑。

陆飞捷
2023-03-14

解决这个问题的另一种方法是使用Quickselect。这应该会给你一个O(n)的总平均时间复杂度。考虑一下:

  1. 使用Quickselect(O(n))查找第k个最大数x

(如果有重复的元素,可以通过计算需要添加到结果中的x的重复数来避免这些元素。)

您的问题与您链接到的SO问题中的问题之间的区别在于您只有一百万个元素,因此它们绝对可以保存在内存中以允许正常使用Quickselect。

 类似资料:
  • 我试图找到给定排序数组的最大K数。 ex:输入- 到目前为止,我编写的代码返回最大的K元素,但它需要返回最大的K数字。任何帮助都将不胜感激。

  • 给定一个未排序的数组,我试图找到最接近数组中位数的 K 个元素。我在线性运行时间内找不到解决方案。 这里的中位数是6。 答案是2,3,4,5,6。 任何帮助或提示将不胜感激。

  • 这可能是微软的面试问题。 从排序的数组中找出第k个最小的元素(忽略重复项) [编辑]:数组可能包含重复项(未指定)。 想了很多次,但仍然质疑自己:还有更好的解决方案吗? 取最大堆 时间复杂度:O(NlogK) 空间复杂度:O(K) 这些元素可能是重复的。所以,通过与以前的元素进行比较来检查是否有唯一的元素 还可以使用改进版的快速排序分区算法。但它可能会导致最坏的情况,因为数组已经排序<这里出现了两

  • 如果您有长度的排序数组,请查找其中最小的元素。这里有一些潜在的解决方案,有些涉及最小堆或二进制搜索,但我想知道使用QuickSelect的时间复杂度是多少。如果我们简单地将每个数组连接在一起,并在组合数组上使用quickselect。 Quickselect在一般情况下以线性时间运行,但是数组的组合确实会扩展搜索空间,但它比使用合并策略更有效,因为如果选择了好的枢轴,Quickselect必然允许

  • 所以我正在研究一个Leetcode问题,我的代码在某些情况下有效,但在某些情况下失败。 问题是: 给定一个矩阵,其中每个行和列都按升序排序,找出矩阵中第k个最小的元素。 请注意,它是排序顺序中的第k个最小元素,而不是第k个独立元素。 例子: 返回: 13 我的方法是使用minHeap,即使它声明数组已经排序,我仍然需要确保我已经将它从最小值排序到最大值。 这是我的代码: 以下是我的意见: 以下是输

  • 本文向大家介绍JS求Number类型数组中最大元素方法,包括了JS求Number类型数组中最大元素方法的使用技巧和注意事项,需要的朋友参考一下 如何使用JS,在一个Number类型的数组里,查找最大(或最小)数呢? 以下介绍四个方法。 1. 不使用任何库函数 代码如下: 解释: 利用一个变量result来存储最大值。遍历待查找的数组,如果当前遍历的元素大于result,就把这个元素赋值给resul