堆heapq(python)
常用方法:
函数名 | 描述 |
---|---|
heappush(heap, item) | 将 item 元素加入堆。 |
heappop(heap) | 将堆中最小元素弹出。 |
heapify(heap) | 将堆属性应用到列表上。 |
heapreplace(heap, x) | 将堆中最小元素弹出,并将元素x 入堆。 |
merge(*iterables, key=None, reverse=False) | 将多个有序的堆合并成一个大的有序堆,然后再输出。 |
heappushpop(heap, item) | 将item 入堆,然后弹出并返回堆中最小的元素。 |
nlargest(n, iterable, key=None) | 返回堆中最大的 n 个元素。 |
nsmallest(n, iterable, key=None) | 返回堆中最小的 n 个元素。 |
基本使用:
h = []
if len(h):heapify(h) #如果list有内容就先构建堆
heappush(h, 5)
heappop(h)
h[0] #第一个元素便是根,即最小值
题目列表
数据流中的第 K 大元素
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
请实现 KthLargest 类:
KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
题目ID:703
- 解题思路
对于可能重复的数组来说,第K大元素类型题目直接使用优先队列来进行处理。
- 实现代码
class KthLargest:
def __init__(self, k: int, nums: List[int]):
self.nums = nums
self.k = k
heapq.heapify(self.nums)
def add(self, val: int) -> int:
heapq.heappush(self.nums,val)
while len(self.nums)>self.k:
heapq.heappop(self.nums)
return self.nums[0]#
- 细节
heapq是直接对list进行操作
heapq只有小顶堆,nums[0]最小
如需实现大顶堆,将push的值用相反数即可实现
TopK也可使用heapq.nlargest得到TopK个数字,但是在数据量大时效率低,K越大,耗时越长。
可以到达的最远建筑
给你一个整数数组 heights ,表示建筑物的高度。另有一些砖块 bricks 和梯子 ladders 。
你从建筑物 0 开始旅程,不断向后面的建筑物移动,期间可能会用到砖块或梯子。
当从建筑物 i 移动到建筑物 i+1(下标 从 0 开始 )时:
如果当前建筑物的高度 大于或等于 下一建筑物的高度,则不需要梯子或砖块
如果当前建筑的高度 小于 下一个建筑的高度,您可以使用 一架梯子 或 (h[i+1] - h[i]) 个砖块
如果以最佳方式使用给定的梯子和砖块,返回你可以到达的最远建筑物的下标(下标 从 0 开始 )。
题目ID:1642
- 解题思路:
每次遍历先使用贪心用砖块
如果砖块不够
用梯子替换以前使用的最大砖块数目
- 实现代码:
class Solution:
def furthestBuilding(self, heights, bricks, ladders):
hq = []
for i in range(1, len(heights)):
diff = heights[i] - heights[i - 1]
if diff > 0:
heapq.heappush(hq, -diff)
bricks -= diff
if bricks < 0:
if ladders:
ladders -= 1
bricks -= heapq.heappop(hq)
else:return i - 1
return len(heights) - 1
- 细节:
用负数的方法实现大根堆
每次先把本次需要用到的砖头push入堆
保证砖头不够时,有梯子一定能通过这个围墙