这是Cormen文本中的问题,但我想看看是否还有其他解决方案。
给定一个具有n个不同数字的数组,您需要在数组中找到m个最大的数组,并且具有 他们按排序顺序。假设n和m很大,但生长方式不同。特别是,你需要 在下面考虑m = t * n的情况,其中t是一个小数,比如0.1,然后是 可能性m =√n。
本书中给出的解决方案提供了3种选择:
这些都是有道理的,而且它们各有利弊,但我想知道,还有另外一种方法吗?它不一定更好或更快,我只是想知道这是否是更多解决方案的常见问题,或者我们是否仅限于这三种选择。
答案 0 :(得分:3)
您提到的三种方法的时间复杂性如下:
因此,在渐近复杂度方面,选项(3)肯定比其他选项更好,因为m <= n。当m很小时,(2)和(3)之间的差异很小,几乎没有实际影响。
至于解决问题的其他方法,你可以有很多方法,所以在这方面问题有点差。我能想到的另一种方法是实际上简单和高效,如下所示。
如果m非常小,我只会这样做。如果你有一个最大堆实现并且工作得很好,那么原始列表中的选项(2)也非常容易实现。
答案 1 :(得分:3)
一种不同的方法。
取前m个数字,然后将它们变成最小堆。运行数组,如果其值超过前m的min,则提取min值并插入新值。当您到达数组的末尾时,您可以将元素提取到数组中并反转它。
此版本的最差情况是O(n log(m))
将其置于第一种和第二种效率方法之间。
平均情况更有趣。平均只有O(m log(n/m))
个元素将通过第一个比较测试,每次O(log(m))
工作,所以你得到O(n + m log(n/m) log(m))
工作,这将它放在第二个和第三个方法之间。 但如果n
比m
多出几个数量级,那么O(n)
块占主导地位,而第三种方法中的O(n)
中位数选择具有比这种方法中每个元素的一个比较更糟的常数,所以在这种情况下,这实际上是最快的!