LeetCode-Python 队列专题(学习笔记+代码)

Leetcode641.设计双端循环队列

实现 MyCircularDeque 类:

MyCircularDeque(int k) :构造函数,双端队列最大为 k 。
boolean insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true ,否则返回 false 。
boolean insertLast() :将一个元素添加到双端队列尾部。如果操作成功返回 true ,否则返回 false 。
boolean deleteFront() :从双端队列头部删除一个元素。 如果操作成功返回 true ,否则返回 false 。
boolean deleteLast() :从双端队列尾部删除一个元素。如果操作成功返回 true ,否则返回 false 。
int getFront() ):从双端队列头部获得一个元素。如果双端队列为空,返回 -1 。
int getRear() :获得双端队列的最后一个元素。 如果双端队列为空,返回 -1 。
boolean isEmpty() :若双端队列为空,则返回 true ,否则返回 false  。
boolean isFull() :若双端队列满了,则返回 true ,否则返回 false 。

示例 1:

输入
["MyCircularDeque", "insertLast", "insertLast", "insertFront", "insertFront", "getRear", "isFull", "deleteLast", "insertFront", "getFront"]
[[3], [1], [2], [3], [4], [], [], [], [4], []]
输出
[null, true, true, true, false, 2, true, true, true, 4]

解释

MyCircularDeque circularDeque = new MycircularDeque(3); // 设置容量大小为3
circularDeque.insertLast(1);			        // 返回 true
circularDeque.insertLast(2);			        // 返回 true
circularDeque.insertFront(3);			        // 返回 true
circularDeque.insertFront(4);			        // 已经满了,返回 false
circularDeque.getRear();  				// 返回 2
circularDeque.isFull();				        // 返回 true
circularDeque.deleteLast();			        // 返回 true
circularDeque.insertFront(4);			        // 返回 true
circularDeque.getFront();				// 返回 4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-circular-deque
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
使用Python强大的列表

class MyCircularDeque:
    def __init__(self, k: int):
        self.maxl = k
        self.deque = []

    def insertFront(self, value: int) -> bool:
        if len(self.deque) == self.maxl:
            return False
        self.deque.insert(0, value)
        return True

    def insertLast(self, value: int) -> bool:
        if len(self.deque) == self.maxl:
            return False
        self.deque.append(value)
        return True

    def deleteFront(self) -> bool:
        if not self.deque:
            return False
        self.deque.pop(0)
        return True

    def deleteLast(self) -> bool:
        if not self.deque:
            return False
        self.deque.pop()
        return True

    def getFront(self) -> int:
        if not self.deque:
            return -1
        return self.deque[0]

    def getRear(self) -> int:
        if not self.deque:
            return -1
        return self.deque[-1]

    def isEmpty(self) -> bool:
        return not self.deque

    def isFull(self) -> bool:
        return len(self.deque) == self.maxl

Leetcode题239、滑动窗口最大值

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值

[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

示例 2:

输入:nums = [1], k = 1
输出:[1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sliding-window-maximum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

python内置的堆是最小堆,所以在元素入堆的时候取负,以便求最大值。另外我们需要判断最大值是否在当前的窗口内,所以需要索引值,在入堆的时候一起存入。每次取堆内最大值,也就是堆顶元素的时候,检查索引值是否是在窗口内的。

class Solution:
	def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
		res, heap = [], []
		for i in range(len(nums)):
			heapq.heappush(heap, (-nums[i], i))
			if i + 1 >= k:
				while heap and heap[0][1] <  i + 1 - k:
					heapq.heappop(heap)
				res.append(-heap[0][0])                                               
		return res
    			  

双端队列

class Solution:
    def maxSlidingWindow(self, nums, k):
        d = collections.deque()	#建立一个双端队列
        out = []
        for i, n in enumerate(nums):	#遍历数组
            while d and nums[d[-1]] < n:	#检查到本窗口的值比当前值小,pop掉
                d.pop()
            d += i	#把当前值加入窗口中
            #这样队列中第0位永远是最大的
            if d[0] == i - k:	#检查最大值是否已经不在窗口中,不在就丢掉,因为每一步都检查,所以不会漏
                d.popleft()	#第一个窗口看到本窗口内最后一个值的时候才能找到最大值,所以从k-1处开始记录结果
            if i >= k - 1:
                out += nums[d[0]]
        return out
    			    

动态规划

class Solution:
    def maxSlidingWindow(self, nums, k):
        n = len(nums)
        if n * k == 0: return []
        if k == 1: return nums
        left, right = [0] * n, [0] * n
        left[0] = nums[0]
        right[n - 1] = nums[n - 1]

        for i in range(1, n):
            if i % k == 0:
                left[i] = nums[i]
            else:
                left[i] = max(left[i - 1], nums[i])

            j = n - i - 1
            if (j + 1) % k == 0:
                right[j] = nums[j]
            else:
                right[j] = max(right[j + 1], nums[j])
        output = []
        for i in range(n - k + 1):
            output.append(max(left[i + k - 1], right[i]))
        return output

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值