https://mp.weixin.qq.com/s/FFsvWXiaZK96PtUg-mmtEw
从arr[1, n]这n个数中,找出最大的k个数,这就是经典的TopK问题。
1、排序 时间复杂度:O(nlg(n))
2、局部排序:冒泡法 时间复杂度:O(nk)
3、堆排序:只找到TopK,不排序TopK。时间复杂度:O(nlg(k))
先用前k个元素生成一个小顶堆,这个小顶堆用于存储,当前最大的k个元素。
接着,从第k+1个元素开始扫描,和堆顶(堆中最小的元素)比较,如果被扫描的元素大于堆顶,则替换堆顶的元素,并调整堆,以保证堆内的k个元素,总是当前最大的k个元素。
直到,扫描完所有n-k个元素,最终堆中的k个元素,就是猥琐求的TopK。
分治法(Divide&Conquer),把一个大的问题,转化为若干个子问题(Divide),每个子问题“都”解决,大的问题便随之解决(Conquer)。这里的关键词是“都”。从伪代码里可以看到,快速排序递归时,先通过partition把数组分隔为两个部分,两个部分“都”要再次递归。
减治法(Reduce&Conquer),把一个大的问题,转化为若干个子问题(Reduce),这些子问题中“只”解决一个,大的问题便随之解决(Conquer)。这里的关键词是“只”。
快速排序:O(nlg(n))
二分查找:O(lg(n))
随机选择:O(n)
