力扣刷题Day 13 | 239. 滑动窗口最大值,347.前 K 个高频元素

239. 滑动窗口最大值

题目链接

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

视频讲解

单调队列正式登场!| LeetCode:239. 滑动窗口最大值_哔哩哔哩_bilibili

笔记

  1. 思路是维护一个单调递减的双端队列,队列左端即为最大值。每次移动窗口加入元素时,若队列的元素比当前元素小,则不用继续维护,将小的元素弹出队列,直到队列为空或队尾元素大于等于要加入的元素时,把要加入的元素添加到队尾。每次移动窗口时还要将上一个滑动窗口最左端的值弹出队列,如果要弹出的值和队列左端最大值相等则弹出,不等则说明在加入元素时上一个滑动窗口最左端的值就已经被弹出了。
  2. 用双端队列涉及到弹出队列最左端的元素,如果直接用列表,删除元素时涉及到后面元素的顺序移位,时间复杂度为O(n),因此需要导入Python的容器collections中的双端队列数据结构deque(double ended queue),它在左端加入和弹出元素的复杂度都是O(1)的。collections --- 容器数据类型 — Python 3.11.4 文档
  3. 创建一个类MyQueue,实现单调队列的pop、push及front操作

Python代码

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): # 若push的值大于队列入口元素,那么将队列入口的已有元素弹出
        while self.queue and value > self.queue[-1]:
            self.queue.pop()
        self.queue.append(value) # 最后加入新的元素
    
    def front(self): # 查询队列出口处的元素,即最大值
        return self.queue[0]

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        que = MyQueue()
        res = []
        for i in range(k): # 先将前k个元素加入队列
            que.push(nums[i])
        res.append(que.front()) # res存放当前窗口内的最大值
        for i in range(k,len(nums)):
            que.pop(nums[i-k]) # 将上一个滑动窗口最左端的元素移出队列
            que.push(nums[i]) # 将滑动窗口右端新加入的元素加入队列
            res.append(que.front()) # 将滑动窗口最大的元素加入结果数组
        return res


347.前 K 个高频元素

题目链接

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

视频讲解

优先级队列正式登场!大顶堆、小顶堆该怎么用?| LeetCode:347.前 K 个高频元素_哔哩哔哩_bilibili

笔记

  1. 偷懒,直接用Counter了

Python代码

from collections import Counter

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        tmp = Counter(nums).most_common(k)
        res = []
        for i in tmp:
            res.append(i[0])
        return res

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值