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

239. 滑动窗口最大值

看题解之前只想到了暴力思路。
如果按照提示使用队列的话,有问题搞不清楚,如果维护一个排序从大到小的队列时,滑动窗口的移除的元素怎么移除?新添加的元素如何放到合适的地方?

看了题解之后
1、队列没有必要维护窗口所有元素,只需要维护窗口中有可能成为最大值的元素就可以了
2、保证队列里的元素数值是由大到小的
那么这个维护元素单调递减的队列就叫做单调队列,即单调递减或单调递增的队列。
实现的单调队列有这三个函数可以满足题目要求,pop(移除不在窗口的元素),push(添加新元素),front(获取队首元素即最大值)。

理解一下,在构造单调队列的时候,窗口中最大值出现在队首,因为在不断读取窗口元素的时候,遇见大的值时 之前小的值会被移除。
为什么能被移除呢?因为遇到大的值后前面小的值已经没有机会成为最大值了,没有必要保留,因此队首肯定是最大值。
添加元素时如果小于前面的元素,需要添加,因为前面最大值不在滑动窗口之后,这个值是有可能成为最大值的;
如果大于,前面的元素没有可能成为最大值,被移除。
注意:如果添加的元素等于前面的元素,需要添加,如果不添加在pop的时候会错误移除元素。例如 [-7,-8,7,5,7,1,6,0]  4

from collections import deque

class MyQueue:
    def __init__(self):
        self.queue = deque()

    def pop(self, value):
        if self.queue and self.queue[0] == value:
            return self.queue.popleft()

    def push(self, value):
        while self.queue and self.queue[-1] < value:
            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]:
        my_queue = MyQueue()
        res = []
        for index, num in enumerate(nums):
            my_queue.push(num)
            if index+1 < k:
                continue
            res.append(my_queue.front())
            my_queue.pop(nums[index-k+1])
        return res

347.前 K 个高频元素

思路

  1. 统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素

在对频率进行排序的时候,使用优先队列是最优的,因为只需要维护K个有序序列,复杂度从O(nlogn)降低到O(nlogk),使用小顶堆


Python中实现优先队列可以使用heapq, queue.PriorityQueue, list    
参考文档
https://builtin.com/data-science/priority-queues-in-python
https://zhuanlan.zhihu.com/p/67642557
https://docs.python.org/zh-cn/3.10/library/heapq.html

这道题目参考别人的代码学习一下,没用过heapq

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        # 统计字符出现的频率
        count = collections.Counter(nums)
        heap = []
        for key, val in count.items():
            if len(heap) >= k:
                if val > heap[0][0]:
                    heapq.heapreplace(heap, (val, key))
            else:
                heapq.heappush(heap, (val, key))
        return [item[1] for item in heap]

你可能感兴趣的:(算法)