239 滑动窗口最大值
需要构造单调递减队列,为保持单调性:每次从队尾加入新元素时,如果新元素大于队尾元素则不断将队尾元素pop出,直至新元素小于队尾元素(或队列为空)时,再把新元素压入队尾
那么每次返回队头元素即为本滑动窗口的最大值,将这些最大值保留起来返回结果
暴力解法时间复杂度显然O(nk),此解法每个元素只被push和pop一次,时间复杂度为O(n)
from collections import deque
class PriorityQue:
def __init__(self):
self.que = deque()
def push(self, x):
while self.que and x > self.que[-1]:
self.que.pop()
self.que.append(x)
def pop(self, x):
if self.que:
if x == self.que[0]:
self.que.popleft()
def front(self):
if self.que:
return self.que[0]
class Solution:
def maxSlidingWindow(self, nums: list[int], k: int) -> list[int]:
que = PriorityQue()
maxList = list()
for i in range(k):
que.push(nums[i])
maxList.append(que.front())
for i in range(k, len(nums)):
que.pop(nums[i - k])
que.push(nums[i])
maxList.append(que.front())
return maxList
347 前 K 个高频元素
使用Python heapq堆队列module(该实现为小顶堆,堆元素可以为元组,符合本题要求),每次弹出的是最小的元素,当堆的大小超过k,立即heappop出其中最小的元素,遍历完字典后堆的大小就是k,内为前k个高频元素(此时heappop这k个时候也是从小到大,强迫症的话可以最后返回时反序)
时间复杂度,统计频率为O(n),使用堆队列维护前k个时需要遍历字典最多n次,每次push和pop的复杂度为O(logk),所以总共时间复杂度为O(nlogk)
空间复杂度因为需要统计频率为O(n),队列额外空间为O(k),最终空间复杂度为O(n)
import heapq
class Solution:
def topKFrequent(self, nums: list[int], k: int) -> list[int]:
di = dict()
for num in nums:
di[num] = di.get(num, 0) + 1
que = list()
for key, value in di.items():
heapq.heappush(que, (value, key))
if len(que) > k:
heapq.heappop(que)
res = list()
for _ in range(len(que)):
res.append(heapq.heappop(que)[1])
return res