1438. 绝对差不超过限制的最长连续子数组
这个题目看到要找一个最长连续的子数组,就可以知道肯定是要用滑动窗口的,但是我们不能简单的套用滑动窗口的模板,题目的一个限制是,窗口内的最大元素减最小元素的差值要小于等于limit。如果我们每次都对窗口求一次最大最小值,时间复杂度就$O(N)\times k$,k是窗口的长度,在这个题目是需要超时的。既然每次都需要最大最小值。和我之前写这篇文章是类似的 leetcode-239. 滑动窗口最大值 。维护一个单调队列,我们就能在$O(1)$的时间复杂度查询最值,只不过这个题目即需要最大值,又需要最小值,我们需要维护两个单调队列。
from collections import deque
class Solution:
def longestSubarray(self, nums: List[int], limit: int) -> int:
max_dq = deque()
min_dq = deque()
res = 0
l = 0
for i, num in enumerate(nums):
while max_dq and num >= nums[max_dq[-1]]:
max_dq.pop()
max_dq.append(i)
while min_dq and num <= nums[min_dq[-1]]:
min_dq.pop()
min_dq.append(i)
while nums[max_dq[0]] - nums[min_dq[0]] > limit:
if max_dq[0] == l:
max_dq.popleft()
if min_dq[0] == l:
min_dq.popleft()
l += 1
res = max(res, i - l + 1)
return res
239题缩小窗口是可以用if的,因为是定长的,每次最多就缩一次,但是这里一定是需要用while的,有可能移除了一个元素之后,依然是不符合条件需要继续缩小的。缩小完之后的窗口一定是符合条件的,更新答案就可以了。
原创
leetcode-1438. 绝对差不超过限制的最长连续子数组
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法