Top问题常见具体场景问法、算法及时间空间复杂度分析

(1)有10000000个记录,这些查询串的重复度比较高,如果除去重复后,不超过3000000个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。请统计最热门的10个查询串,要求使用的内存不能超过1GB。

(2)有10个文件,每个文件1GB,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。按照query的频度排序。

(3)有一个1GB大小的文件,里面的每一行是一个词,词的大小不超过16个字节,内存限制大小是1MB。返回频数最高的100个词。

(4)提取某日访问网站次数最多的那个IP。

(5)10亿个整数找出重复次数最多的100个整数。

(6)搜索的输入信息是一个字符串,统计300万条输入信息中最热门的前10条,每次输入的一个字符串为不超过255B,内存使用只有1GB。

(7)有1000万个身份证号以及他们对应的数据,身份证号可能重复,找出出现次数最多的身份证号。

此处不再赘述其他排序方法,最优方法无疑是堆排序。

堆排序是通过维护大顶堆或者小顶堆来实现的。

堆排序法来解决N个数(非常大)中的TopK的思路是:

1、先随机取出N个数中的K个数,将这N个数构造为小顶堆,那么堆顶的数肯定就是这K个数中最小的数了。

2、然后再将剩下的N-K个数与堆顶进行比较,如果大于堆顶,那么说明该数有机会成为TopK,就更新堆顶为该数。

3、此时由于小顶堆的性质可能被破坏,就还需要调整堆;否则说明这个数最多只能成为Top K+1 th,丢弃不用管它。

4、然后就将下一个数与当前堆顶的数作比较,根据大小关系如上面所述方法进行操作,直到N-K个数都遍历完,

5、此时堆中的K个数就是TopK。

复杂度分析:

根据堆排序的复杂度,不难得出,在该方法中,首先需要对K个元素进行建堆,时间复杂度为O(K);然后对剩下的N-K个数对堆顶进行比较及更新,最好情况下当然是都不需要调整了,那么时间复杂度就只是遍历这N-K个数的O(N-K),这样总体的时间复杂度就是O(N),而在最坏情况下,N-K个数都需要更新堆顶,每次调整堆的时间复杂度为logK,因此此时时间复杂度就是NlogK了,总的时间复杂度就是O(K)+O(NlogK)≈O(NlogK)。

空间复杂度是O(1)。

值得注意的是,堆排序法提前只需读入K个数据即可,可以实现来一个数据更新一次,能够很好的实现数据动态读入并找出TopK。

发布了279 篇原创文章 · 获赞 23 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_30242987/article/details/104797113