题目描述
假设一个固定大小为W的窗口,依次划过arr,返回每一次滑出状况的最大值。
例如,arr = [4,3,5,4,3,3,6,7], W = 3
返回:[5,5,5,4,6,7]
思路
维护一个双向链表,双向链表从左到右的元素单调递减。定义两个指针L和R,向右滑动指针R,若当前元素小于链表最右侧元素,则从右侧加入链表;若不满足,从右侧依次弹出链表中的元素,直到满足单调递减条件后再从右侧加入链表。
若链表最左侧元素超出窗口区域了,则从左侧弹出元素。
时间复杂度:O(n)
空间复杂度:O(n)
代码
class WindowMaxArray:
"""
24 窗口内最大值或最小值的更新结构
窗口内最大值或最小值更新结构的实现
假设一个固定大小为W的窗口,依次划过arr,
返回每一次滑出状况的最大值
例如,arr = [4,3,5,4,3,3,6,7], W = 3
返回:[5,5,5,4,6,7]
"""
def solution(self, nums: List[int], n: int):
"""
双端队列
:param nums: [4,3,5,4,3,3,6,7]
:param n: 3
:return: [5,5,5,4,6,7]
"""
if not nums or n <= 0:
return None
arr = [0]*(len(nums)-n+1)
dq = deque()
dq.append(0)
i, cnt = 0, 0
n = min(len(nums), n)
for i in range(1, n):
if nums[i] >= nums[dq[-1]]:
dq.clear()
dq.append(i)
arr[cnt] = nums[dq[0]]
for i in range(n, len(nums)):
if dq[0] + n <= i:
dq.popleft()
if nums[i] <= nums[dq[0]]:
if nums[i] <= nums[dq[-1]]:
dq.append(i)
else:
while nums[i] > nums[dq[-1]]:
dq.pop()
dq.append(i)
else:
dq.clear()
dq.appendleft(i)
cnt += 1
arr[cnt] = nums[dq[0]]
return arr