【代码随想录训练营】【Day 11】【栈与队列-3】| Leetcode 239, 347
需强化知识点
- 单调队列:单调递减或递增的队列
- 堆:大顶堆,小顶堆
题目
239. 滑动窗口最大值
- 代码随想录思路:单调队列 维护有可能成为窗口里最大值的元素,保证队列里的元素是从大到小的
- 单调队列规则:
- pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
- push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止
- 每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。
- 代码解读:
- que 记录的是当前窗口中可能为最大值的元素,队首为当前最大值
- 先处理前k的元素,并记录当前的最大值结果
- 滑动窗口处理元素,先移除最前面的元素,然后加入当前窗口最后的元素
from collections import deque
class MyQueue:
def __init__(self):
self.queue = deque()
def pop(self, value):
if self.queue and value == self.queue[0]:
self.queue.popleft()
def push(self, value):
# -1 为队尾
while self.queue and value > self.queue[-1]:
self.queue.pop()
self.queue.append(value)
def front(self):
# 返回队首
return self.queue[0]
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
que = MyQueue()
result = []
# 先将前k的元素放入队列
for i in range(k):
que.push(nums[i])
result.append(que.front()) # 记录前k的元素的最大值
for i in range(k, len(nums)):
que.pop(nums[i-k])
que.push(nums[i])
result.append(que.front())
return result
347. 前 K 个高频元素
- 代码随想录思路 : 小顶堆
- 代码流程:
- 统计元素出现频率
- 构建小顶堆(依照频率),如果堆的大小大于k,弹出堆顶元素
- 倒叙构建数组
import heapq
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
map_ = {}
for i in range(len(nums)):
map_[nums[i]] = map_.get(nums[i], 0) + 1
# 定义一个小顶堆,大小为k,对频率排序
pri_que = []
for key, freq in map_.items():
# (freq, key) 是要插入的元组,freq 表示优先级或权重,key 是要插入堆中的值
# python 默认构建的是小顶堆,如果想要构建大顶堆,可以将key * -1
heapq.heappush(pri_que, (freq, key))
if len(pri_que) > k:
# 从堆中删除并返回具有最小优先级的元素
heapq.heappop(pri_que)
result = [0] * k
for i in range(k-1, -1, -1):
result[i] = heapq.heappop(pri_que)[1]
return result
本文介绍了如何使用Python解决LeetCode中的两个问题:239滑动窗口最大值,利用单调队列保持窗口内的最大值;以及347前k个高频元素,通过小顶堆统计元素频率并返回前k个最常见的元素。

2万+

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



