- 自定义单调队列
- 不需要维护窗口里的所有元素,只需要维护有可能成为最大值的元素 - > 所以在push新元素进去时,就可以直接将该元素之前的,比该元素小的值pop出去,这样也可以确保出队口的元素是最大值,方便执行getMax
- 在pop时,除了要检查队列非空之外,还要检查需要移除的nums位置的元素(即pop函数传入的value)是否与我们队列出口处一致,如果相等才需要pop,如果不相等,则说明nums该位置的元素并没有被维护在队列中,不需要再进行pop
- 在主函数中,每次循环只需要执行pop+push+front即可完成滑动窗口的移动
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):
while self.queue and value > self.queue[-1]:
self.queue.pop()
self.queue.append(value)
def front(self):
return self.queue[0]
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
queue = MyQueue()
result = []
for i in range(k):
queue.push(nums[i])
result.append(queue.front())
for i in range(k, len(nums)):
queue.pop(nums[i-k])
queue.push(nums[i])
result.append(queue.front())
- 时间复杂度 O(nlogk)
- 空间复杂度 O(n)
- 使用优先级队列 -> 小顶堆
- 不能使用大顶堆,因为每次将最大的元素弹出的话,并不符合题目要求
import heapq
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
map_ = {}
for i in range(len(nums)):
map_[nums[i]] = map_.get(nums[i], 0) + 1
pri_que = []
for key, freq in map_.items():
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