代码随想录算法训练营第十三天丨239. 滑动窗口最大值,347.前 K 个高频元素

文章介绍了如何通过单调队列和小顶堆(heapq)的数据结构解决滑动窗口问题中的最大值计算,以及如何使用heapq找到前K个高频元素。作者通过实例展示了heapq的heappush、heappop等方法在这些问题中的应用。

239. 滑动窗口最大值

单调队列,自己在实现的时候遇到了不知道怎么判断是否在窗口内的问题。最终通过类似单调栈的存入索引解决。

from collections import deque
class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        res = []
        monoQue = deque() #存索引,便于判断窗口移动

        for i in range(len(nums)):
            if monoQue and monoQue[0] < i - k + 1: #移除不在窗口内的元素
                monoQue.popleft()
            
            while monoQue and nums[i] >= nums[monoQue[-1]]:
                monoQue.pop()
            
            monoQue.append(i)

            if i >= k - 1: 
                res.append(nums[monoQue[0]])
        return res

347. 前 K 个高频元素

学习heapq,小顶堆。heapq提供了对堆队列算法的支持,也称为优先队列算法。堆是一种特殊的树形数据结构,其每个父节点的值都小于或等于其所有子节点的值(这种堆称为最小堆)或者每个父节点的值都大于或等于其所有子节点的值(这种堆称为最大堆)。在heapq模块中,堆以列表的形式实现,但不是普通的列表。列表的第一个元素总是最小的,这是堆的一个重要特性。

  1. heapq.heappush(heap, item):将 item 元素添加到 heap 中,并保持堆的不变性。
  2. heapq.heappop(heap):弹出并返回 heap 中最小的元素,保持堆的不变性。如果堆为空,抛出 IndexError。
  3. heapq.heappushpop(heap, item):将 item 放入堆中,然后弹出并返回 heap 中最小的元素。该组合操作比 heappush() 后跟 heappop() 更高效。
  4. heapq.heapify(x):将列表 x 转换成堆,即重新排列列表 x 使其符合堆的性质。
  5. heapq.nlargest(n, iterable, key=None):返回 iterable 中第 n 大的元素。
  6. heapq.nsmallest(n, iterable, key=None):返回 iterable 中第 n 小的元素。

另外,在Python的 heapq 中,堆元素可以是元组。这种情况下,元组的第一个元素将用于比较(例如(freq, num) 中的 freq)。如果第一个元素相同,则比较下一个元素,以此类推。这就是为啥可以将 (freq, num) 作为元素添加到堆中,并且 heapq 会根据 freq 来维护堆的顺序。

import heapq
from collections import Counter
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        count = Counter(nums)
        heap = []

        for num,freq in count.items():
            if len(heap) < k:
                heapq.heappush(heap,(freq,num))
            else:
                if freq >= heap[0][0]:
                    heapq.heappop(heap)
                    heapq.heappush(heap,(freq,num))
        
        return [num for freq,num in heap]

另外提一嘴,找最大的k个,维护小顶堆是因为在代码中每次将堆顶的小的元素扔掉了,换了个比他大的进来再重排堆,这样经过一次遍历,heap数组中就只剩下最大的k个了。

今日总结:

虽然不愿意承认,今天的主题是优先队列的朴素思想:“如果一个年纪小的人比你还强,那你就可以退役了。”

堆在最近看堆排序时有所了解,使用库实现并不麻烦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值