239. 滑动窗口最大值
单调队列,自己在实现的时候遇到了不知道怎么判断是否在窗口内的问题。最终通过类似单调栈的存入索引解决。
from collections import deque
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
res = []
monoQue = deque() #存索引,便于判断窗口移动
for i in range(len(nums)):
if monoQue and monoQue[0] < i - k + 1: #移除不在窗口内的元素
monoQue.popleft()
while monoQue and nums[i] >= nums[monoQue[-1]]:
monoQue.pop()
monoQue.append(i)
if i >= k - 1:
res.append(nums[monoQue[0]])
return res
347. 前 K 个高频元素
学习heapq,小顶堆。heapq提供了对堆队列算法的支持,也称为优先队列算法。堆是一种特殊的树形数据结构,其每个父节点的值都小于或等于其所有子节点的值(这种堆称为最小堆)或者每个父节点的值都大于或等于其所有子节点的值(这种堆称为最大堆)。在heapq模块中,堆以列表的形式实现,但不是普通的列表。列表的第一个元素总是最小的,这是堆的一个重要特性。
- heapq.heappush(heap, item):将 item 元素添加到 heap 中,并保持堆的不变性。
- heapq.heappop(heap):弹出并返回 heap 中最小的元素,保持堆的不变性。如果堆为空,抛出 IndexError。
- heapq.heappushpop(heap, item):将 item 放入堆中,然后弹出并返回 heap 中最小的元素。该组合操作比 heappush() 后跟 heappop() 更高效。
- heapq.heapify(x):将列表 x 转换成堆,即重新排列列表 x 使其符合堆的性质。
- heapq.nlargest(n, iterable, key=None):返回 iterable 中第 n 大的元素。
- heapq.nsmallest(n, iterable, key=None):返回 iterable 中第 n 小的元素。
另外,在Python的 heapq 中,堆元素可以是元组。这种情况下,元组的第一个元素将用于比较(例如(freq, num) 中的 freq)。如果第一个元素相同,则比较下一个元素,以此类推。这就是为啥可以将 (freq, num) 作为元素添加到堆中,并且 heapq 会根据 freq 来维护堆的顺序。
import heapq
from collections import Counter
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
count = Counter(nums)
heap = []
for num,freq in count.items():
if len(heap) < k:
heapq.heappush(heap,(freq,num))
else:
if freq >= heap[0][0]:
heapq.heappop(heap)
heapq.heappush(heap,(freq,num))
return [num for freq,num in heap]
另外提一嘴,找最大的k个,维护小顶堆是因为在代码中每次将堆顶的小的元素扔掉了,换了个比他大的进来再重排堆,这样经过一次遍历,heap数组中就只剩下最大的k个了。
今日总结:
虽然不愿意承认,今天的主题是优先队列的朴素思想:“如果一个年纪小的人比你还强,那你就可以退役了。”
堆在最近看堆排序时有所了解,使用库实现并不麻烦。
文章介绍了如何通过单调队列和小顶堆(heapq)的数据结构解决滑动窗口问题中的最大值计算,以及如何使用heapq找到前K个高频元素。作者通过实例展示了heapq的heappush、heappop等方法在这些问题中的应用。
794

被折叠的 条评论
为什么被折叠?



