偶尔间看到一个问题:从海量数字中找到第k大的数
脑子里蹦出来的第一个念头是堆,复杂度O(nlogk)。后来想想好像在某些情况下可以用快速选择的思想,能达到O(n)。
快速选择的思想很简单,在快速排序的基础上实现,比如选择数字p为比较值,将一组数分为两半,我们将数字p的索引i与k比较就能知道第k个数字是在索引i的左边还是右边,还是恰好是i直接返回,接着只对包含k的那一边继续做相同过程就可以了。下面是go代码实现。
Tab: 其中加入了输出过程,来观察每一步的结果。
package main import ( "fmt" "math/rand" ) func main() { org := rand.Perm(10) value := 7 fmt.Println("原始切片: ", org) fmt.Printf(" 第%d个值: %d\n", value, findKthLargest(org, 0, len(org)-1, value)) fmt.Println("最终切片: ", org) } func findKthLargest(s []int, start, end, k int) int { p := s[end] l := start for i := start; i < end; i++ { if s[i] <= p { fmt.Println(" 交换: i-&#