如果按照牛客网的剑指offer里面的做法,采用改进的快排,那么时间复杂度是O(n)
如果是基本排序的排法,就选择堆排序更快,分析如下:
1、快速排序:在最理想的情况下,即划分可以使得每次分到n/2 的两个序列,复杂度为o(nlogn)。
2、堆排序:无论什么情况都是o(nlogn),当然还有建堆的时间o(n),所以为n+nlogn,但是,本题只是要前五十个,所以堆排序只需要执行50次就够了:n+50logn。
3、本题的条件是1000个无序整数,1000+50log1000<1000log1000,所以自然是堆排序最好。
p.s.:堆排序只需要一个n大小的二叉树就行了,快速排序除了n大小的数组,每次递归最少还得有logn的栈,所以堆排序的空间复杂度也优于快速排序。
构建一个容量为n的堆,建堆时间为n,此后每次都弹出堆顶元素再调整,一共弹50次,每次调整时间为log(n),所以是n+50*log(n);
另外一种思路是只维护一个容量为50的堆,所以建堆的复杂度为50,此后需要遍历数组的所有元素(为n-50个),每个元素都要和堆顶的元素进行比较,根据情况进行插入(称之为堆更新),每次更新的复杂度为lg(50),所以总时间复杂度是:50+(n-50)*lg(50);
因为第一种方法n的系数为1(详见建堆时间复杂度证明),log(n)可以忽略,第二种n的系数是5.64,所以第一种会好一点。不过,对于top K问题中不同的K,这一结论并不是固定的。