动态求前n个最小值(最大值)
作者:互联网
注: 由于最小值和最大值的分析过程完全相同,这里我们只讨论最小值的分析流程,最大值同理
问题描述
每次给定一个数值,询问此数值以及之前给定数值中最小的n
个数
例如给定数值的顺序为:8 7 1 2 9 4
,设n == 3
8
:不足3
个数,则答案为8
7
:不足3
个数,则答案为8 7
1
:不足3
个数,则答案为8 7 1
2
:8 7 1 2
中较小的3个数为7 1 2
9
:8 7 1 2 9
中较小的3个数为7 1 2
4
:8 7 1 2 9 4
中较小的3个数为4 1 2
暴力做法
一个最直观的方法是,每次添加新的数据后,将当前所有数据进行排序,选择较小的n个
一次排序最快也要\(O(nlogn)\),总的复杂度至少要\(O(n^2logn)\)
小根堆和大根堆
维护一个容量为n
的大根堆,堆内元素代表当前最小的n
个值
每次添加数值与堆顶元素进行比较,具有以下两种情况:
- 大于堆顶元素: 由于是大根堆,堆顶元素为最小的
n
个数中的最大值,则此数值一定大于n个数中的其他值,即它一定不属于答案 - 小于堆顶元素:则用它取代堆顶元素则可以使得这
n
个数更小
对于问题描述中所举的例子,使用大根堆的求解流程如下:
8
:不足3
个数,则答案为8
7
:不足3
个数,则答案为8 7
1
:不足3
个数,则答案为8 7 1
2
:2 < 8
, 则答案为7 2 1
9
:9 > 7
,则答案不变为7 2 1
4
:4 < 7
,则答案为4 2 1
总结
动态求前n
个最小值使用大根堆
动态求前n
个最大值使用小根堆
标签:堆顶,求前,最大值,个数,数值,最小值,答案 来源: https://www.cnblogs.com/G-H-Y/p/15865158.html