官方链接:https://docs.python.org/3/library/heapq.html
堆,其实是二叉树的一种。Python中的堆其实是小根堆,即每一个父节点都小于等于它的子节点。
堆这种结构在leetcode刷题过程中经常遇到。
对于一个堆heap来说,它最小的元素总是它的根节点,即heap[0]。
对于一个堆来说,它的导入比较简单
import heapq
heap = []
通过heappush
方法可以将数字加入堆中
heapq.heappush(heap,1)
heapq.heappush(heap,2)
heapq.heappush(heap,3)
heap
#[1,2,3]
通过heappop
的方式,每次返回堆中的最小值。直到heap为空,报错
heapq.heappop(heap)
#1
heapq.heappop(heap)
#2
heapq.heappop(heap)
#3
heapq.heappop(heap)
Traceback (most recent call last):
File "" , line 1, in <module>
heapq.heappop(heap)
IndexError: index out of range
另外,heapq还有heapify
方法,把一个list转化为堆heap。
res = [1,4,3,5,6,2]
heapq.heapify(res)
res
#返回的res是二叉树结构的列表[1, 4, 2, 5, 6, 3]
返回res中最大的两个数
res = [1,4,3,5,6,2]
heapq.nlargest(2,res)
#[6, 5]
返回res中最小的两个数
res = [1,4,3,5,6,2]
heapq.nsmallest(2,res)
#[1,2]
另外,heapq还存在merge(融合多个列表)、heapreplace、heappushpop等其他方法,具体可以查看文档了解。
41. 数据流中的中位数
class MedianFinder(object):
from heapq import *
def __init__(self):
"""
initialize your data structure here.
"""
self.bigHpeap = []
self.smallHeap = []
def addNum(self, num):
"""
:type num: int
:rtype: None
"""
if len(self.bigHpeap) == len(self.smallHeap):#总数为偶数时,先插入到大根堆,在插入到小根堆
heapq.heappush(self.smallHeap, -heapq.heappushpop(self.bigHpeap, -num))
else:#总数为奇数时,先插入到小根堆,在插入到大根堆
heapq.heappush(self.bigHpeap, -heapq.heappushpop(self.smallHeap, num))
def findMedian(self):
"""
:rtype: float
"""
if len(self.bigHpeap) == len(self.smallHeap):
return (-self.bigHpeap[0] + self.smallHeap[0]) / 2.0
else:
return self.smallHeap[0]
23. 合并K个排序链表
合并K个排序链表,一种比较直接、暴力的方式就是把所有链表值append到一个列表中,排序后重新输出链表。
另一种方式是把每个链表的值放入heap,然后通过pop()每次自动排出最小值。
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
import heapq
dummy = ListNode(0)
p = dummy
head = []
for i in range(len(lists)):
while lists[i] :
heapq.heappush(head, (lists[i].val, i))
lists[i] = lists[i].next
while head:
val, idx = heapq.heappop(head)
p.next = ListNode(val)
p = p.next
return dummy.next