算法题之找出数组里第K大的数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法题之找出数组里第K大的数相关的知识,希望对你有一定的参考价值。

 

问题:找出一个数组里面前K个最大数。

 

解法一(直接解法):

对数组用快速排序,然后直接挑出第k大的数。这种方法的时间复杂度是O(Nlog(N))。N为原数组长度。

这个解法含有很多冗余,因为把整个数组都排序了,而实际上我们不需要这样做。

 

解法二(K数组排序):

首先,创建一个长度为K的空数组。从原数组中先挑出K个数进行排序并放到这个空数组中。这一步的时间复杂度是O(Klog(K))。

接着,从剩下的N-K个值中,依次遍历并与上面数组的末尾的数(即里面的最大数)相比较,并插入到合适位置。这一步的时间复杂度是O(N-K)。

总平均时间复杂度是O(Klog(K)+(N-K))。

 

解法三(递归法):

当K值非常大或非常接近N的时候,那么上面的两种解法的时间复杂度都会显著增大,这就需要有更好的方法来应对。

假设N=100万,K=50万的情况。

先选取一个中值元素(该中值是否合理将影响到算法效率,其原因同快速排序),然后将大于等于该数的元素放到其右侧,小于该数的放到左侧。如7 4 6 8 0 -1,选取6作为中值元素,则结果应该为4 0 -1 6 8 7,接下来比较K值和现在的中值元素6所在索引(3)。
如果K小于索引3,则处于包括中值元素在内的右边的元素即是前K个最大数中的前(3(索引) - K + 1)个最大数,予以保存,同时需在索引0 ~ 2间再进行递归操作继续选取第K名。
如果K大于索引3,则在4 ~ 5中递归选取第K - 3(索引) - 1名即可。
还有一关键是可以为递归中的数组长度选取一临界点,小于该临界则进行全排序,而不再进行递归操作。

平均时间复杂度是O(N)。

当问题规模不是很大时,比如数组大小N很小,N为100数量级,可以不用太追求算法的高效性,因为对于问题规模不大时,上面三种算法的运行时间相差并不大,
完全可以考虑采用第一种或者第二种比较简单的实现方式。

 

以上是关于算法题之找出数组里第K大的数的主要内容,如果未能解决你的问题,请参考以下文章

无序数组中找第k大的数

LeetCode 215. Kth Largest Element in an Array(排序)

两个有序数组的中位数(第k大的数)

从数组中找出第K大的数

滴滴笔试1.连续数组的最大和 2.找出数组中第K大的数

Matlab/simulink:一个数组 不用排序的方法 找出它当中第K大的数