代码随想录算法训练营day13| 239. 滑动窗口最大值、347. 前K个高频元素、栈与队列总结

239、滑动窗口最大值

from collections import deque


class Solution(object):
    def __init__(self):
        self.q = deque()

    def pop_value(self, val):
        if self.q and self.q[0] == val:
            self.q.popleft()

    def push(self, val):
        while self.q and val > self.q[-1]:
            self.q.pop()
        self.q.append(val)

    def get_value(self):
        return self.q[0]

    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        res = []
        for i in range(k):
            self.push(nums[i])
        for j in range(len(nums)-k+1):
            res.append(self.get_value())
            if j+k >= len(nums):
                break
            self.pop_value(nums[j])
            self.push(nums[j+k])
        return res

需构造一个单调队列,其中push方法需要从尾端比较和pop元素,要注意不能从头端,队列里不一定要维持K个元素,只要保证最大元素位于头端,遍历时可拿到就行,移除头部元素时要判断是否是当前要移除的元素

347、前K个高频元素

class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        from collections import defaultdict
        hash_map = defaultdict(int)
        for i, c in enumerate(nums):
            hash_map[c] += 1
        return sorted(set(nums), reverse=True, key=lambda x: hash_map[x])[:k]

用sorted直接排序,时间复杂度nlogn

进阶方法(优先级队列暨小顶堆法):

class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        hash_map = {}
        for c in nums:
            hash_map[c] = hash_map.get(c, 0) + 1
        import heapq
        heap = []
        for key, val in hash_map.items():
            heapq.heappush(heap, (val, key))
            if len(heap) > k:
                heapq.heappop(heap)
        res = [0] * k
        for i in range(k-1, -1, -1):
            res[i] = heapq.heappop(heap)[1]
        return res

解决该问题分三个步骤,对元素出现频率进行统计,对统计好的频率排序,输出前K个高频元素

主要是对频率排序,构造一个长度为K的优先级队列(小顶堆),对map里的pair进行排序,因为小顶堆不断弹出堆顶的最小优先级的pair,所以最后留下来的是前K个高频元素,最后再倒叙输出即可,不用大顶堆是因为需要构造map长度也就是N的堆,而小顶堆只需要维护K个键值对即可

总结:

栈和 队列都是属于容器适配器,根据其容器底层实现方式不同,具有不同的特性,栈是属于后入先出,特别适合于解决匹配类问题,涉及到的经典题目有括号匹配,相邻字符串去除重复项,逆波兰表达式等,队列涉及到的经典题目有滑动窗口最大值,前K个高频元素等,分别用到了单调队列以及优先级队列,python语言中栈不是内置结构,可以用列表,deque等实现,队列有双端队列deque,以及queue模块包含的各种队列,还有优先级队列(堆排序)可以用heapq实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值