LeetCodeDiary

A Diary for solving LeetCode problems

View on GitHub
'''
Description: 
Autor: Au3C2
Date: 2021-02-21 12:54:35
LastEditors: Au3C2
LastEditTime: 2021-02-21 12:54:55
'''
class Solution:
    def longestSubarray(self, nums: List[int], limit: int) -> int:
        # 栈底维护了最值,栈顶维护了窗口终点

        ascend, descend = [], [] # 维护一个最小值栈,一个最大值栈
        a, d = 0, 0 # 队首下标
        t = 0 # 窗口起始点
        res = 0

        for i in range(len(nums)): # i为窗口终止点,利用循环滑动终止点
            temp = nums[i] # 保存终止点对应的值

            # 更新最小值
            while len(ascend) > a and temp < ascend[-1][0]: # 与栈顶值对比
                ascend.pop() # 弹出
            ascend.append((temp, i)) # 记录终点值与下标
            
            # 更新最大值
            while len(descend) > d and temp > descend[-1][0]: # 与栈顶值对比
                descend.pop() # 弹出
            descend.append((temp, i)) # 记录终点值与下标

            while descend[d][0] - ascend[a][0] > limit: # 最值之差大于limit出发滑动条件
                t += 1 # 起始点滑动
                if ascend[a][1] < t: # 如果窗口起点在最小值索引右侧,需要舍弃此时的最小值
                    a += 1
                if descend[d][1] < t: # 如果窗口起点在最大值索引右侧,需要舍弃此时的最大值
                    d += 1
            
            res = max(res, i-t+1) # 更新最大长度

        return res
    
# 数组,中等,每日一题
# https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/