刷题第十一天 239.滑动窗口最大值 347. 前k个高频元素

239. 滑动窗口最大值

暴力解法超时了

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        result = []
        _list = [] 
        i = 0
        while i < len(nums):
            if i < k:
                _list.append(nums[i])
                i += 1
            else:
                result.append(max(_list))
                _list = _list[1:]
                _list.append(nums[i])
                i += 1
        result.append(max(_list))
        return result

利用python双端队列 deque()来构造单调队列ddque()

from collections import deque
class ddeque():
    def __init__(self):
        self._list = deque()

    def pop_left_(self , val):
        if self._list[0] == val:
            self._list.popleft()

    def push_right_(self, val):
        while self._list and self._list[-1] < val:
            self._list.pop()
        self._list.append(val)

    def get_max_(self):
        return self._list[0]
    
    def print(self):
        return self._list

class Solution:

    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        result = []
        _list = ddeque()
        i = 0
        while i < len(nums):
            if i < k:
                _list.push_right_(nums[i])
                i += 1
            else:
                result.append(_list.get_max_())
                _list.pop_left_(nums[i - k])
                _list.push_right_(nums[i])
                i += 1
        result.append(_list.get_max_())
        return result

基本思想是

左端pop_left(val) 如果窗口中需要左出的值和单调队列中最左端的值(默认是最大值,因为是单调队列)相等 那么就再单调队列中pop_left() 否则不做操作,这样保证了单调队列最左端的值就一直是滑动窗口中的最大值。

右端push_right_(val): 如果窗口中需要右进的值比单调队列中最右端的值大,那么就单调队列最右端的值右出一个,就是pop() "pop()默认是出右端",那么直到找到单调队列中最右端的值比需要右进的值大,则把这个值加入单调队列

这两个操作保证了 1. 单调队列中最左端的值就是滑动窗口的最大值 2. 队列是单调递减的

所以如果滑动窗口中的最大值要出去了,单调队列中的最大值也对应左出,那么第二大的值就候补上来。由于右端push_right_的操作,可以保证单调队列中是按最大值,第二大,第三大的顺序排列,从而不会遗漏最大值。

另外对于python deque()的双端队列:

1. .append(): 右添加元素

2. .appendleft():左添加元素

3. .pop(): 右弹出元素并返回右端元素

4. .popleft(): 左弹出元素并返回左端元素

5. .reverse(): 原地反转

6. .insert(i,x): 在位置i插入x

7. .count(x): 计算deque中元素x出现的次数

8. .clear(): 清空

9. .remove(): 移除找到的第一个元素

347. 前K个高频元素

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        dic = {}
        result = []
        for i in nums:
            if i not in dic:
                dic[i] = 1
            else:
                dic[i] += 1
        sorted_dic = sorted(dic.items(), key = lambda item: item[1], reverse = True)
        i = 0
        for key,val in sorted_dic:
            result.append(key)
            i += 1
            if i >= k:
                break
        return result

利用哈希表的思想 统计每个数字出现的频率,然后对字典排序,降序排列之后输出前k个的键

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值