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