代码训练营打卡第十三天|239.滑动窗口最大值,347.前 K 个高频元素

栈与队列——239.滑动窗口最大值,347.前 K 个高频元素

文档链接:代码随想录
做题感悟:

  • 滑动窗口最大值:利用单调队列实现对滑动窗口最大值的判断,通过遍历滑动窗口,更新队列的同时,得到每个滑动窗口最大值
  • 前k个高频元素;哈希表+小顶堆。其中python利用heapq模块实现小顶堆结构。小顶堆在push和pop过程中仍然会维护小顶堆的结构
  • 顺便再回忆下哈希表的访问方式。

题目一:239.滑动窗口最大值——40min

题目链接:题目
文档链接:文档
视频讲解:视频

在这里插入图片描述

  • 为了实现滑动窗口最大值
  • 首先需要实现对滑动窗口的左侧pop,右侧push,同时返回最大值
  • 为了保证寻找最大值的复杂度尽可能的小,可以构建一个单调队列,再更新队列的同时保证队列的第一个元素始终是最大值,进而降低复杂度。
  • 在pop队列的最大值时,先判断是否是滑动窗口要pop的元素
  • 在push元素的时候,先判断前面的元素是否比当前元素大,如果大于就pop,进而保证了队列的单调性。
  • 由于队列是滑动窗口的子集,同时队列单调,因此就能保证队列的第一个元素是滑动窗口的最大值。
class Mydeque:
    # 定义一个单调队列的基本操作,保证队列内的元素永远是第一个最大,单调递减
    def __init__(self):
        self.deque=deque() # 初始化队列
    def pop(self,value: int) -> None:
        if self.deque and self.deque[0] == value:
            self.deque.popleft()
        return
        # 如果是滑动窗口pop的元素正好是队列末尾的元素,则pop该元素。
        # 保证队列内元素是滑动窗口元素的子集,并且起始元素是最大值。
        # 如果不相等,实际上也会被push操作给淘汰了。
    def push(self,value: int) -> None:
        while self.deque and value > self.deque[-1]:
            self.deque.pop() # 将小于value的值从右边pop
        self.deque.append(value)
        return
    
    def getmax(self):
        return self.deque[0]

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        # 定义三个函数。
        # pop,如果滑动窗口起始下标的前一个是当前最大值,则将最大值pop
        # push,如果滑动窗口下一个要放进去的数值比前面的都大,则将前面的元素pop。
        # getmax,获得当前队列的最大值。
        # python的队列为双向队列,利用popleft从down推出,利用pop实现将元素从top推出。
        que = Mydeque()
        ans=[]
        for i in range(k):
            que.push(nums[i])
        ans.append(que.getmax())
        for i in range(k,len(nums)):
            que.pop(nums[i-k])
            que.push(nums[i])
            ans.append(que.getmax())
        return ans

题目二:347.前 K 个高频元素——80min

题目链接:题目
文档链接:文档
视频讲解:无

在这里插入图片描述

  • python的heapq库使用。
  • 先用哈希表求频次复杂度为log(n)
  • 在用小顶堆,保证堆内元素永远是前k个,多出来的元素则被pop出去。
  • heapq.heappop(haep_):表示pop最小元素,同时维持小顶堆结构。如果pop后的元素为空,则会出现错误。可以用heap_[0]进行访问。
    在这里插入图片描述
import heapq
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
    # 利用堆结构实现堆排序。
    # 先用哈希表求频次
    # 利用长度为k的堆,寻找前K个高频元素
    # 利用小顶堆,在超过k个元素的情况下,将根节点pop。保证小顶堆内的元素始终是最大的前k个元素
        map_={}
        for i in range(len(nums)):
            map_[nums[i]] = map_.get(nums[i],0)+1 
            # 记住python访问字典的方式,以及记录频次的方式
        heap_= []
        for key,freq in map_.items():
            heapq.heappush(heap_,(freq,key)) # 小顶堆以第一个数值为标准
            if len(heap_)>k:
                heapq.heappop(heap_)
        result=[0]*k

        for i in range(len(result)):
            result[i] = heap_[i][1]
        return result

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值