heapq
模块提供了堆队列算法的实现,也称为优先队列算法
堆的创建
我们可以可以使用两种方式来创建堆。一个是使用 heapq.heappush
的方式来向堆中不断的填充元素。另外一种方式是使用 heapq.heapify()
来将list转化为heap结构。
For example
1 2 3 4 5 6 7 8 9
| import heapq l = [1,2,3,4] heap = []
for val in l: heapq.heappush(heap,val)
heapq.heapify(l)
|
堆的访问
弹出最小值
可以使用函数 heapq.heappop(heap)
来弹出堆中的最小值。传入的参数类型为堆
For example
1 2 3 4
| import heapq nums = [1,3,2,5,4] heapq.heapify(nums) print(heapq.heappop(nums))
|
弹出当前最小值并添加一个新的元素
可以使用函数 heapq.heapreplace
来在弹出最小值后再添加一个元素。
For example
1 2 3 4 5 6
| import heapq nums = [1,3,2,5,4] heapq.heapify(nums) heapq.heapreplace(nums,1.5)
print(nums[0])
|
使用 nums[0]
可以快捷的访问当前堆的最小值
添加一个新元素并弹出当前堆的最小值
可以使用函数 heapq.heappushpop(heap,item)
来实现将一个元素放入堆中后,返回当前堆的最小值。
For Example
1 2 3 4 5 6 7 8
| import heapq nums = [1,3,2,5,4] heapq.heapify(nums) print(heapq.heappushpop(6,nums)) print(nums)
|
获取当前堆的最小或者最大值
如果需要获取当前堆前n个的最小值或者最大值,可以使用 heapq.nlargest()
or heapq.nsmalles()
For example
1 2 3 4 5 6 7 8
| import heapq nums = [1,3,2,5,4] heapq.heapify(nums) print(heapq.nlargest(2,nums)) print(heapq.nsmallest(2,nums))
|
应用
Leetcode 703题 数据流中的第 K 大元素
题目要求:
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
请实现 KthLargest 类:
KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 输入: ["KthLargest", "add", "add", "add", "add", "add"] [[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]] 输出: [null, 4, 5, 5, 8, 8]
解释: KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]); kthLargest.add(3); kthLargest.add(5); kthLargest.add(10); kthLargest.add(9); kthLargest.add(4);
|
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import heapq class KthLargest: def __init__(self,k:int,nums:List[int]): self.pool = nums heapq.heapify(self.pool) self.k = k while len(self.pool) > k: heapq.heappop(self.pool) def add(self,val:int) -> int: if len(self.pool) < self.k: heapq.heappush(self.pool,val) elif val > self.pool[0]: heapq.heapreplace(self.pool,val) return self.pool[0]
|
解答思路
维持一个最大为K的最小堆。每次添加元素,如果元素大于堆的最小值,则将当前堆的最小值pop,然后将元素push到堆中。最后返回元素添加后的最小值。如果当前堆的大小小于K,则直接将此元素添加到堆中。然后返回堆的最小值。
参考
[1] https://leetcode-cn.com/problems/kth-largest-element-in-a-stream
[2] https://docs.python.org/zh-cn/3/library/heapq.htm
[3] https://www.jianshu.com/p/801318c77ab5