239.滑动窗口最大值
力扣链接
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
思路1 暴力遍历
让活动窗口依次移动过去
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
left = 0
right = left + k
res = []
while right <= len(nums):
res.append(max(nums[left:right]))
left += 1
right = left + k
return res
但是这种方法在输入较大时会超出时间限制。
思路2 单调队列
单调队列,即单调递减或单调递增的队列,python中的单调队列要自己实现。对于此题需要找最大值的情况,利用单调递减队列是合适的。
我们需要一个单调递减队列,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。
每次窗口移动的时候,调用que.pop,que.push,然后que.front()就返回我们要的最大值。
并且,队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了
设计单调队列的时候,pop,和push操作要保持如下规则:
- pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
- push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止
保持如上规则,每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。
class myqueue:
def __init__(self):
self.queue = deque()
def pop(self, val): # 如果要移出窗口的值就是队列头的值,则直接弹出
if self.queue and val == self.queue[0]:
self.queue.popleft()
def push(self, val): # 如果要push的值大于队列尾的值,则将队列尾的弹出。让push的值成为最小的
while self.queue and val > self.queue[-1]:
self.queue.pop()
self.queue.append(val)
def front(self):
return self.queue[0]
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
que = myqueue()
res = []
# 先将前k个元素放入que
for i in range(k):
que.push(nums[i])
res.append(que.front())
for i in range(k, len(nums)):
que.pop(nums[i-k]) #输入滑动窗口即将移除的元素进行比较
que.push(nums[i])
res.append(que.front())
return res
347.前 K 个高频元素
力扣链接
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
思路 小顶堆
先创建一个哈希表统计每个元素出现的次数,创建一个小顶堆,把哈希表的元素放进去并按照出现次数排序,如果堆长度大于k则将最顶上的元素pop掉,这样留下的就是出现次数最多的元素。
import heapq # 默认小顶堆
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
# 构建字典统计出现次数
mydict = dict()
for num in nums:
if num not in mydict:
mydict[num] = 1
else:
mydict[num] += 1
# 定义一个大小为k的小顶堆
pri_que = []
for key, freq in mydict.items():
heapq.heappush(pri_que,(freq, key))# 向小顶堆中放置元素,根据freq调整排序
if len(pri_que)>k:# 如果超过k了,就把堆顶的pop出去
heapq.heappop(pri_que)
# print(pri_que)
result = []
for i in pri_que:
result.append(i[1])
return result