【代码随想录训练营】【Day 11】【栈与队列-3】| Leetcode 239, 347

本文介绍了如何使用Python解决LeetCode中的两个问题:239滑动窗口最大值,利用单调队列保持窗口内的最大值;以及347前k个高频元素,通过小顶堆统计元素频率并返回前k个最常见的元素。

【代码随想录训练营】【Day 11】【栈与队列-3】| Leetcode 239, 347

需强化知识点

  • 单调队列:单调递减或递增的队列
  • 堆:大顶堆,小顶堆

题目

239. 滑动窗口最大值

  • 代码随想录思路:单调队列 维护有可能成为窗口里最大值的元素,保证队列里的元素是从大到小的
  • 单调队列规则:
    • pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
    • push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止
    • 每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。
  • 代码解读:
    • que 记录的是当前窗口中可能为最大值的元素,队首为当前最大值
    • 先处理前k的元素,并记录当前的最大值结果
    • 滑动窗口处理元素,先移除最前面的元素,然后加入当前窗口最后的元素
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):
        # -1 为队尾
        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()
        result = []

        # 先将前k的元素放入队列
        for i in range(k):
            que.push(nums[i])
        result.append(que.front())  # 记录前k的元素的最大值

        for i in range(k, len(nums)):
            que.pop(nums[i-k])
            que.push(nums[i])
            result.append(que.front())
        return result

347. 前 K 个高频元素

  • 代码随想录思路 : 小顶堆
  • 代码流程:
    • 统计元素出现频率
    • 构建小顶堆(依照频率),如果堆的大小大于k,弹出堆顶元素
    • 倒叙构建数组
import heapq

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        map_ = {}
        for i in range(len(nums)):
            map_[nums[i]] = map_.get(nums[i], 0) + 1
        
        # 定义一个小顶堆,大小为k,对频率排序
        pri_que = []

        for key, freq in map_.items():
        	# (freq, key) 是要插入的元组,freq 表示优先级或权重,key 是要插入堆中的值
        	# python 默认构建的是小顶堆,如果想要构建大顶堆,可以将key * -1
            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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值