给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html
方法一:暴力解法,超时
nums = [1,3,-1,-3,5,3,6,7]
k = 3
def fun():
arr = []
n = k
for i in range(len(nums)-k+1):
arr.append(max(nums[i:n]))
n += 1
return arr
print(fun())
方法二:单调队列
import collections
class MyQueue:
def __init__(self):
self.queue = collections.deque()
def push(self,x):
# 当队列不为空,同时新增的值大于前面的值时(不一定是最前端的最大值值),就持续把小于当前值的删掉,删完之后把新增的值加进来
# 这里有两种情况,一种是最大值大于新增值,那么就会形成单调队列(前面的删除了一部分)
# 最大值小于新增值,那么最后队列内就只会有新增值(前面的全部删除了)
while self.queue and x > self.queue[-1]:
self.queue.pop()
self.queue.append(x)
def pop(self,x):
# 从前端删除
if self.queue and x ==self.queue[0]:
self.queue.popleft()
def get_max_value(self):
return self.queue[0]
nums = [1, 3, -1, -3, 5, 3, 6, 7]
k = 3
que = MyQueue()
res = []
for i in range(k):
que.push(nums[i])
res.append(que.get_max_value())
for i in range(k,len(nums)):
que.push(nums[i])
que.pop(nums[i-k])
res.append(que.get_max_value())
print(res)
分析:
1.为什么要保留pop方法?
2.双端队列,最右边(前端)始终放最大值,当新进来的值大于前面的值,那么就从最后面(后端)开始删除,一直删到队列单调递增
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0347.%E5%89%8DK%E4%B8%AA%E9%AB%98%E9%A2%91%E5%85%83%E7%B4%A0.html
import heapq
nums = [1,1,1,2,2,3]
k=2
def fun():
dic = {}
lis = []
# 第一步:获取所有元素的出现频率
for i in nums:
dic[i] = dic.get(i,0)+1
# 第二步:通过小顶堆获取出现频率最高的元素
for e,times in dic.items():
# 遍历字典,把每一组数据推入lis中
heapq.heappush(lis,(times,e)) # 元素e和times频率,在放入lis时位置交换了,主要是因为要根据频率排序
# 只需要维护k组数据,超过k个的直接删除,这里pop是从最小的开始删除
if len(lis) > k:
heapq.heappop(lis)
# 第三步:由于lis的顺序是从小到大(map结构),题目要求只返回元素,所以结果需要先整理再返回
return [i[1] for i in lis[::-1]]
print(fun())
记录代码随想录的思路:
这道题目主要涉及到如下三块内容:
首先统计元素出现的频率,这一类的问题可以使用map来进行统计。
然后是对频率进行排序,这里我们可以使用一种 容器适配器就是优先级队列。
什么是优先级队列呢?
而且优先级队列内部元素是自动依照元素的权值排列。那么它是如何有序排列的呢?
缺省情况下priority_queue利用max-heap(大顶堆)完成对元素的排序,这个大顶堆是以vector为表现形式的complete binary tree(完全二叉树)。
什么是堆呢?
heapq 是 Python 标准库中的模块,用于实现堆数据结构(heap)的操作。堆是一种特殊的二叉树结构,具有以下特点:
Python 的 heapq 模块提供了一些函数,可以对列表(可看作是一个完全二叉树)进行堆操作,包括插入元素、删除最小/最大元素等。以下是 heapq 模块中常用的一些函数:
可以使用 import heapq 语句导入 heapq 模块,然后通过调用上述函数来进行堆操作。通常情况下,要使用堆进行排序,首先使用 heapify() 将列表转换为堆,然后使用 heappop() 或其他函数来获取排序后的元素。
示例:
import heapq
# 创建一个空堆
heap = []
# 添加元素到堆中
heapq.heappush(heap, 4)
heapq.heappush(heap, 2)
heapq.heappush(heap, 8)
heapq.heappush(heap, 1)
# 弹出并打印堆中的最小元素
print(heapq.heappop(heap)) # 输出: 1
# 将列表转换为堆
list1 = [6, 3, 9, 5]
heapq.heapify(list1)
print(list1) # 输出: [3, 5, 9, 6]
通过使用 heapq 模块,可以在 Python 中方便地实现堆数据结构的操作。