1438.绝对差不超过限制的最长连续子数组

显然我们是需要同时维护当前的最大值和最小值,这就需要两个单调队列dq_down(递减排列)一个维护最大值,dq_up(递增排列)一个维护最小值,同样这个是使用我们第二个模板 [left, i]. 

只有当left等于某一个dq.front()的时候,才把它pop_front().这就使得对应相同的元素,我们只需要保留一个就行,也就是说在队尾遇见了相同的元素,我们可以直接加入,也可以删除相同的再加入.

class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {
        deque<int> dq_up;
        deque<int> dq_down;
        int left=0,ans=0;
        for(int i=0;i<nums.size();i++){
            while(!dq_up.empty() && nums[i]<=nums[dq_up.back()]){
                dq_up.pop_back();     
            }
            dq_up.push_back(i);
            while(!dq_down.empty() && nums[i]>=nums[dq_down.back()]){
                dq_down.pop_back();
            }
            dq_down.push_back(i);
            
            while(!dq_up.empty() && !dq_down.empty() && nums[dq_down.front()]-nums[dq_up.front()]>limit){
                if(left==dq_up.front()){
                    dq_up.pop_front();
                }
                if(left==dq_down.front()){
                    dq_down.pop_front();
                }
                left++;   
            }

            ans=max(ans,i-left+1);
        }
        return ans;
    }
    // s.erase(s.find(nums[left++])) 改成: s.erase(nums[left++])
    //前者是使用迭代器删除,是只删除一个元素
    //后者是使用重载的value删除,删除所有等于value的元素
};

        开始的时候我一直担心pop_back这里会影响left, 也就是说为了维护单调性会删除错误的元素,但是后来我发现其实不会,因为它删除的元素都是在left边界之前的, 不会影响left

        而且其实最后一个while可以写成if, 因为每次最多只需要删除一个元素, right只会+1  而之前的ans已经保存了上一次 r-l+1 的正确的数值  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值