C.滑动窗口——2762. 不间断子数组

题目链接:2762. 不间断子数组(中等)

算法原理:

解法:滑动窗口+单调队列

击败94.13%

时间复杂度O(N)

这里单调队列的作用与下题是一样的👇(其实除了统计方式不同,其余基本完全相同😂,所以注释这里就不再赘述了)

本质就是找最大值最小值来判断,因为已经用一个for循环来找滑动窗口了,再用一个for循环找最值,时间复杂度直接飙升到O(N²)级别了,所以用单调队列来优化,因为可以让找最值降到O(1)级别:

①maxQ队首一定是当前窗口的最值:队首最旧最大的元素(单调性保证最值)+窗口范围[left,right]保证在窗口内,minQ同理

②队列出掉的元素再也用不上:遍历到right时,在当前窗口内的元素就是maxQ里的最大值,旧的最大值就算不出掉也用不上,出掉还能防止干扰,保证最大值最新,minQ同理

A.每日一题------3578. 统计极差最大为 K 的分割方式数

博主第一次做的时候犯的错误:以left对应元素为基准,只要符合[left-2,left+2]就算进去,代码如下:

java 复制代码
class Solution {
    public long continuousSubarrays(int[] nums) {
        //滑动窗口维护:两两之间数值差<=2的连续子数组
        int n=nums.length;
        int ret=0; 
        for(int left=0,right=0;right<n;right++){
            //取标准
            int cur=nums[left];
            int l=cur-2,r=cur+2;
            //进窗口
            if(nums[right]>=l&&nums[right]<=r)
                ret+=right-left+1;
            //出窗口
            if(nums[right]<l||nums[right]>r){
                left=right-1;
                right-=2;
                ret--;
            }
        }
        return ret;
    }
}

但其实这是错误的,因为以left对应元素为基准取"±2 区间",只能保证right位置的元素和left的差≤2,但无法保证窗口内其他元素之间的差也≤2,比如5为基准时区间是[3,7],3、7与5之间都符合要求,但3和7的差是4,不符合要求

Java代码:

java 复制代码
class Solution {
    public long continuousSubarrays(int[] nums) {
        Deque<Integer> minQ=new ArrayDeque<>();
        Deque<Integer> maxQ=new ArrayDeque<>();
        int n=nums.length;
        long ret=0;
        for(int left=0,right=0;right<n;right++){
            //进窗口
            int x=nums[right];
            //maxQ队首一定是当前窗口的最值:队首最旧最大的元素(单调性保证最值)+窗口范围[left,right]保证在窗口内,minQ同理
            //队列出掉的元素再也用不上:遍历到right时,在当前窗口内的元素就是maxQ里的最大值,旧的最大值就算不出掉也用不上,出掉还能防止干扰,保证最大值最新,minQ同理
            while(!minQ.isEmpty()&&x<=nums[minQ.peekLast()]) minQ.pollLast();
            minQ.addLast(right);
            while(!maxQ.isEmpty()&&x>=nums[maxQ.peekLast()]) maxQ.pollLast();
            maxQ.addLast(right);
            //出窗口
            while(nums[maxQ.peekFirst()]-nums[minQ.peekFirst()]>2){
                left++;
                if(minQ.peekFirst()<left) minQ.pollFirst();
                if(maxQ.peekFirst()<left) maxQ.pollFirst();
            }
            //更新
            ret+=right-left+1;
        }
        return ret;
    }
}
相关推荐
Anastasiozzzz1 分钟前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
骇客野人3 分钟前
通过脚本推送Docker镜像
java·docker·容器
刘琦沛在进步5 分钟前
【C / C++】引用和函数重载的介绍
c语言·开发语言·c++
机器视觉的发动机17 分钟前
AI算力中心的能耗挑战与未来破局之路
开发语言·人工智能·自动化·视觉检测·机器视觉
铁蛋AI编程实战20 分钟前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
HyperAI超神经25 分钟前
在线教程|DeepSeek-OCR 2公式/表格解析同步改善,以低视觉token成本实现近4%的性能跃迁
开发语言·人工智能·深度学习·神经网络·机器学习·ocr·创业创新
晚霞的不甘31 分钟前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays101133 分钟前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
R_.L35 分钟前
【QT】常用控件(按钮类控件、显示类控件、输入类控件、多元素控件、容器类控件、布局管理器)
开发语言·qt
Zach_yuan44 分钟前
自定义协议:实现网络计算器
linux·服务器·开发语言·网络