239. 滑动窗口最大值、 347.前 K 个高频元素
题目:滑动窗口最大值
题解:
1)使用一个单调递减队列。从最大到最小。因为没有现成的这种数据结构,我们需要自己写一个。滑动窗口每次移动之后,push进来被划过的数值,pop出去被划出的数值。
2)为了保证绝对从大至小,在push的时候要保证这个数比当前队列尾的值要小,如果大的话,就要将它之前的所有元素都弹出。因此pop的时候,如果待pop的元素不在栈中,就意味着在push的时候有被删除。
3)注意这里要用collections.deque包,如果单纯用list来模拟,这道题可能会超时。deque是一个双向队列,是指从队首和队尾都可以进行pop和push的数据结构。这个包的使用基本和list一致吧,self.queue[0],[-1]可以定位头尾。
代码:
from collections import deque
#注意这个myQueue要完全靠自己定义:
#记录几个错误,在class myQueue后面不应该有括号,每个函数里边都是self,参数;__init__q前后两个杠杠
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):#为了保证这是一个单调递减序列
while self.queue and val > self.queue[-1]:
self.queue.pop()
self.queue.append(val)
def returnMax(self):
return self.queue[0]
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
res = []
slidwindows = myQueue()
for i in range(k):
slidwindows.push(nums[i])
res.append(slidwindows.returnMax())
for i in range(k,len(nums)):
slidwindows.pop(nums[i - k])
slidwindows.push(nums[i])
res.append(slidwindows.returnMax())
return res
题目:前K个高频元素
题解:
1) 应用到了小顶堆的知识,它是一个数据结构,详见小顶堆。使用的时候,应该先新建一个空列表,再逐个元素push进去,即可形成所需堆。
2) 根本上来说就是headpush, headpop两个方法,小顶堆是指一个完全二叉树,堆顶元素是所有元素中最小的。注意:python里边的优先队列原则:如果headpush进去的是多维列表,那么是按照第一维度进行排序的!!
代码:
import heapq
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
freq = {}
for n in nums:
if n not in freq:
freq[n] = 0
freq[n] += 1
xiaoding = []
for key, value in freq.items():
heapq.heappush(xiaoding, (value, key))
if len(xiaoding) > k:
heapq.heappop(xiaoding)
res = [0] * k#注意这里,如果下面需要数组从后往前赋值,那么应该先定义数组长度
for i in range(k-1, -1, -1):#这里要注意,如果是倒数,也是左闭右开的原则。
#这里的意思是[k-1,0)
res[i] = heapq.heappop(xiaoding)[1]
return res