Top K 问题小结

222 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

原文链接:blog.csdn.net/roufoo/arti…

  1. 不管是一维数组还是二维或多维数组求第K小或第K大元素,如果数组是无序的,那么

求第K小的元素就用最大堆,

求第K大的元素就用最小堆。

如果是一维数组,时间复杂度是O(NlogK)。如果是二维数组,时间复杂度是O(MNlogK)。 注意,这里也可以是一个链表,或者M个链表,做法一样,时间复杂度也一样。

  1. 不管是一维数组还是二维或多维数组求第K小或第K大元素,也可以用quick select算法。 数组不需要有序。 如果是一维数组,时间复杂度是O(N)。如果是二维数组,时间复杂度是O(MN)。

一维数组的quick select 见Lintcode 80 Median blog.csdn.net/roufoo/arti…

注意,quick select不能用链表。

  1. 如果一维数组是有序的,直接取第k个或第n-k个元素即可。 如果二维数组每个数组都是有序的,那么 求第K小的元素就用最小堆, 求第K大的元素就用最大堆。

如果是二维矩阵,时间复杂度是O(M+KlogM)。这里M是建堆复杂度。

二维数组的例子见Lintcode 1874 Kth Smallest Element in a Specific Array blog.csdn.net/roufoo/arti…

  1. 如果二维数组行列都是有序的,那么 求第K小的元素用最小堆 求第K大的元素用最大堆 以求第K小的元素用最小堆为例,思路是先放matrix[0][0],即最小的那个元素,然后将其pop(),再把它的正下方和右边的那个元素放进堆, 因为这两个肯定是仅比top大的那两个最小的元素。如此反复,一共pop掉k-1次,并且每次pop掉top后都把它正下方和右方的元素加进来。 时间复杂度O(klogk)。因为循环k遍,每次往里放最多2个数,所以heap最大size是2k,放了最多2k次,pop了k此,时间复杂度O(klogk)。

例子见 LintCode 401. Kth Smallest Number in Sorted Matrix blog.csdn.net/roufoo/arti…

  1. 如果是求前K个most frequent的元素呢?光MaxHeap或MinHeap还不行,因为我们要记录每个元素的frequency。 一个方法是Unordered_map + MaxHeap 另一个方法是Unordered_map + MinHeap blog.csdn.net/roufoo/arti…