滑动窗口模板

Java 滑动窗口算法详解及通用实现模板案例示范 在解决一些子数组或子字符串相关的问题时,**滑动窗口算法**(Sliding Window Algorithm)是一种非常高效的算法策略。它能帮助我们避免使用暴力搜索的方式,减少时间复杂度,尤其在处理大规模数据时表现出色。滑动窗口算法的核心思想是通过一对边界指针来动态调整子数组或子字符串的范围,从而减少不必要的重复计算。 本文将详细讲解滑动窗口算法的原理、通用实现模板及其应用场景,并结合实际案例进行示范。 阅读详情

滑动窗口模板

/* 滑动窗⼝算法框架 */
void slidingWindow(string s, string t) {
	unordered_map<char, int> need, window;
	for (char c : t) need[c]++;
	int left = 0, right = 0;
	int valid = 0;
	while (right < s.size()) {//左闭右开区间
		// c 是将移⼊窗⼝的字符
		char c = s[right];
		// 右移窗⼝
		right++;
		// 进⾏窗⼝内数据的⼀系列更新
		...
	
		// 判断左侧窗⼝是否要收缩
		while (window needs shrink) {
			// d 是将移出窗⼝的字符
			char d = s[left];
			// 左移窗⼝
			left++;
			// 进⾏窗⼝内数据的⼀系列更新
			...
		}
	}
}

76. 最小覆盖子串
在做滑动窗口问题时要明确以下几个问题

  1. 什么时候停止窗口扩张,哪些参数变化
  2. 什么时候停止窗口收缩,哪些参数变化
  3. 是在扩张时更新结果还是收缩时更新结果

对于本题而言,当窗口的字符包含t中的字符时停止扩张,当窗口的字符没有包含t中所有字符时停止收缩,因为这是求最小子串,所以应该是在收缩时更新结果。
准备两个哈希表window,need,need统计t中的词频,window统计s字符串包含t中字符的词频
例如 s=“aabcc”,t=“aa”,window只需要统计a的词频就好了,只要窗口中a的词频>=2就说明找到了一个子串
再准备一个变量valid用来判断是否停止扩张或者收缩、

补充:need.count (c) //查找以c为键的个数
need[c]:如果没有以c为键的键值对,就会自动创建一个

class Solution {
public:
    string minWindow(string s, string t) {
        unordered_map<char,int> window,need;//window只需要统计need中字符的词频
        int left=0;
        int right=0;//[)区间,所以初始时窗口为空
        int start=0;//子串的开始位置
        int len=INT_MAX;//子串的长度
        int valid=0;//窗口中符合条件的字符(字符是t中的每个字符)的个数,当valid==need的长度时就说明找到了一个子串
        string re;//保存最终结果
        for(char c:t){
            need[c]++;//统计t中各字符的个数
        }
        while(right<s.size()){
            char c=s[right];//预进入窗口的字符
            right++;//窗口右移
            if(need.count(c)){//当t中含有c字符时更新window
                window[c]++;
               
                if(window[c]==need[c]){//c字符的个数满足条件
                    valid++;
                }
            }

            while(valid==need.size()){//找到了一个子串,need.size()就是t中的字符数
                
                if(right-left<len){//更新最小子串
                    start=left;
                    len=right-left;
                }
                char d=s[left];
    
                left++;//窗口右移
                if(need.count(d)){//移出窗口的字符是符合条件的字符
                   
                    if(window[d]==need[d]){//窗口中d字符个数等于need中d的个数
                        valid--;
                    }
                    window[d]--;
                }

            }

        }
        re=len==INT_MAX?"":s.substr(start,len);
        return re;
    }
};

567. 字符串的排列
判断s2中是否有s1的某个全排列,所以就是找一个包含s1的某个全排列的窗口,如果这个窗口的大小就是s1的大小,直接返回true。
详细步骤:
开始,不断向右扩张,直到valid==need.size()即找到包含s1中所有字符的窗口,然后再进行收缩,收缩前判断窗口的大小是否等于s1的大小,若是,就直接返回true,否则进行收缩

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        unordered_map<char,int>window,need;
        
        int valid=0;
        int left=0;
        int right=0;

        for(char c:s1){
            need[c]++;
        }
        while(right<s2.size()){
            char in=s2[right];
            right++;
            if(need.count(in)){
                window[in]++;
                if(window[in]==need[in]){
                    valid++;
                }
            }

            while(valid==need.size()){
                if(right-left==s1.size()){//已找到s1的某个全排列
                    return true;
                }
                
                char out=s2[left];
                left++;
                if(need.count(out)){
                    window[out]--;
                    if(window[out]<need[out]){
                        valid--;
                    }
                }
            }

            
        }

       return false;
       
    }
};

438. 找到字符串中所有字母异位词

和上一题一样,也是找全排列的窗口

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        unordered_map<char,int>window,need;
        int left=0;
        int right=0;
        int valid=0;
        vector<int>re;
        for(char c:p){
            need[c]++;
        }
        while(right<s.size()){
            char in=s[right];
            right++;
            if(need.count(in)){
                window[in]++;
                if(window[in]==need[in]){
                    valid++;
                }
            }

            while(valid==need.size()){
                if(right-left==p.size()){//找到一个异位词
                    re.push_back(left);
                }
                char out=s[left];
                left++;
                if(need.count(out)){
                    window[out]--;
                    if(window[out]<need[out]){
                        valid--;
                    }
                }
            }
            
        }
        return re;
    }
};

3. 无重复字符的最长子串

扩张条件:只要当前窗口没有重复字符就扩张
收缩条件:正好与扩张条件相反,有重复字符就收缩
收集结果的时机:扩张时

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char ,int>window;
        int left=0;
        int right=0;
        int minLen=INT_MIN;
        while(right<s.size()){
            char c=s[right];
            right++;
            window[c]++;
            if(window[c]<=1){//要保证当前窗口没有重复值时才可以收集结果
                minLen=minLen>right-left?minLen:right-left;
            }
            while(window[c]>1){//收缩
                char d=s[left];
                left++;
                window[d]--;
            }
        }
        return minLen==INT_MIN?0:minLen;
    }
};

总结

模板固然好用,但是有时候可以要具体问题具体分析,像最后这一题,如果硬套模板反而更加复杂了,总之做滑动窗口题目时主要分析:扩张的条件,收缩的条件,收集结果的时机。

LeetCode 刷题:滑动窗口模板 题目链接:https://leetcode.cn/problems/subarray-product-less-than-k/ 代码: 扩展部分:滑动窗口解题模板 第一个模板:适用于需要使用 [变量] 记录的情况 模板: 例题1: https://leetcode.cn/problems/max-consecutive-ones-iii/ 第二个模板:适用于需要用 [哈希表] 记录的情况 模板: 例题1: 题目链接:https://leetcode.cn/problems/permutation-in 阅读详情

相关推荐

【中兴交换机MC-LAG配置】

​ 中兴mc-lag配置 主设备配置如下: Keepalive链路 interface smartgroup1023 //用作MC-LAG的Keepalive链路接口 switch attribute disable yes description For_Keepalived exit interface xgei-0/1/1/47 switch attribute disable yes description For_Keepalived exit interface

qq_31440733的博客 1万+

【算法】滑动窗口代码模板,轻松解决80道LeetCode题

滑动窗口是双指针的一种特例,可以称为左右指针,在任意时刻,只有一个指针运动,而另一个保持静止。滑动窗口路一般用于解决特定的序列中符合条件的连续的子序列的问题。滑动窗口的时间复杂度是线性的,一般为O(n),滑动窗口的左右边界都不会向左滑动,向左滑动等于走回头路,是一种回溯的算法,很可能会陷入死循环。滑动窗口是一种全遍历问题,一定会遍历到末尾的。其本质思路在于初始化将滑动窗口压满,取得第一个滑动窗口的目标值继续滑动窗口,每往前滑动一次,需要删除一个和添加一个元素,求最优的目标值GitHubGitHub。....

欢迎来到 程序猿 的博客 2575

GraphRAG 踩坑记录

GraphRAG踩坑记录

yufanwenshu的博客 4350

【算法思想·数组】滑动窗口终极模板

滑动窗口本身思路上讲并不复杂,无非是left和right两个指针构建起一个动态window,再根据数据处理需要扩大或缩小窗口。但很多时候我们写滑动窗口总是难以尽善尽美,关键就在于对细节的把控,尤其是对窗口边界值处理不当和窗口变化机制的理解不够本文参考labuladong算法小抄[2、滑动窗口基本框架这个算法技巧的时间复杂度是 O(N),比字符串暴力算法要高效得多。这两个...处的操作分别是扩大和缩小窗口的更新操作,等会你会发现它们操作是完全对称的。

Captain823Jack的博客 1292

PCL 计算点云直线拟合的精度评价标准——直线度

计算点云直线拟合的精度评价标准——直线度

点云侠的博客 1042

【毕设护航】从0构建YOLOv8犬类识别系统,120种犬类精准检测+可视化界面全流程指南

本文介绍了一个基于YOLOv8的120种犬类目标检测与可视化系统毕业设计项目。该项目使用Stanford Dogs数据集,将图像分类任务转化为目标检测任务。主要内容包括:数据预处理(XML标注转换为YOLO格式)、YOLOv8模型训练与测试(包含训练脚本编写和推理实现),以及基于Tkinter的图形界面开发。该项目技术链条完整,涵盖检测、分割等多任务支持,适合作为计算机视觉方向的毕业设计选题,兼具技术深度和展示效果。

LXY_LOVE36的博客 96

【滑动窗口】滑窗模板,在小小的算法题里滑呀滑呀滑

窗口算法是双指针算法的一种特定化的算法模型,常用于在特定的条件下求最大或者最小的字符串,特定的数组,以及字符序列等相关问题

m0_65431718的博客 4477

微店构造订单页面,自动化抢票

之前的文章写过微店抢票如何构造订单页面分析,这篇文章在之前的基础上,进行抢票。

猫敷雪 7201

滑动窗口模板与实践详解

本篇主要总结关于滑动窗口的相关做题技巧与想关例题。理论部分不会涉及。

zdlzf的博客 719

CasADi - 最优控制开源 Python/MATLAB 库

CasADi 是一款开源软件工具,用于数值优化,特别是最优控制(即涉及微分方程的优化)。该项目由 Joel Andersson 和 Joris Gillis 在鲁汶工程大学工程优化中心 (OPTEC) 在读博士生在 Moritz Diehl 的指导下发起。本文档旨在简要介绍 CasADi。

机器人控制与仿真应用 7931

【数据集8】全球人口数据WorldPop详解

全球人口数据WorldPop详解

WW、forever的博客 7879

滑动窗口的模板总结

原来做滑动窗口的题的时候遇到过有一个题解将滑动窗口的模板,但是当时也没有可以的记住,导致现在做题的时候又忘记了. 所以总结一下滑动窗口的java模板; public int windon(int[] nums) { //创建滑动窗口 Map<Character,Integer> map=new HashMap<Character,Integer>(); int max=0; int ans=0; //创建

Oblak_ZY的博客 825

16、Cortex-M7处理器:高性能与复杂架构解析

本文深入解析了Cortex-M7处理器的高性能架构与复杂设计,涵盖AHB总线矩阵优化、超标量六阶段双发射流水线、增强型分支预测单元及双精度浮点支持。重点介绍了其独特的内存层次结构,包括指令与数据TCM、片上缓存和AXI-M 64位总线接口,提升系统并行性与执行效率。通过实际测试对比M4与M7性能差异,并演示如何将代码与数据定位到TCM以实现零等待运行。同时阐述了缓存机制的工作原理及其对系统性能的影响,为开发者提供全面的性能优化指导。

a1b2c3d的博客 126

[滑动窗口小结]关于滑动窗口的大致模板

滑动窗口的Summary

Ranranyo的博客 527

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

leetcode滑动窗口模板之字符串的排列567

滑动窗口 public boolean checkInclusion(String s1, String s2) { if (s1.length()>s2.length()) return false; char[] s1Arr=s1.toCharArray(); char[] s2Arr=s2.toCharArray(); int[] hash=new int[128]; for (char c:s1Arr) hash.

fanzhe的博客 311

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

滑动窗口基本模板(算法)

【代码】滑动窗口基本模板(算法)

m0_46464899的博客 276

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

滑动窗口模板秒杀hot100详解

滑动窗口算法模板解析 滑动窗口算法是一种高效处理数组/字符串子元素问题的技巧,通过维护动态窗口将时间复杂度优化到O(n)。核心思想是使用双指针(left和right)维护窗口,通过移动指针来扩大或缩小窗口。 核心模板步骤: 初始化窗口指针left=0, right=0 扩大窗口(right++)并更新窗口数据 检查条件判断是否需要缩小窗口 缩小窗口(left++)并更新数据 在适当时机更新结果 适用场景: 最小/最大子串问题 子数组和问题 字符串匹配问题 连续子序列问题 优势:相比暴力解法,将O(n²)时间

永不止息 2645

滑动窗口法模板

滑动窗口法用于求满足某种条件的最短或最长子数组(子串)如: 1)最小摘要 2)sum大于target的最短子数组 3)最长的无重复字符的子串 4)最长的最多有k个不同字符的子串 最短子串模板:1)外层循环遍历终点j ,2)内循环:如果当前窗口满足条件,和最最优比并保存,然后起点 i++ for (int j = 0; j < s.size(); j++) { 窗口右端扩展,加

binling的专栏 6845

滑动窗口java模板

今天在力扣刷题目时,发现第三题就不会了 --小小的emo一会 抓住今天学校开运动的机会,没有课 浅浅的学习一下滑动窗口 什么是滑动窗口 :就是寻找最优解 下面是解决办法 1. 当不满足条件时,拓展右边界,当满足条件时,缩短左边界,最后得到一个解并暂存 2.循环第一步,又得到一个解,将其与第一个解相对比,得到最优解并暂存,以此类推 下面就是模板 public int _滑动窗口(String s) { //创建滑动窗口 Map<Character,Integer> ..

m0_54384158的博客 467

C++ 滑动窗口模板

C++ 滑动窗口模板

weixin_45596153的博客 496

滑动窗口解题模板

滑动窗口解题模板 问题 Leetcode 1208 解题模板 #include <bits/stdc++.h> using namespace std; class Solution { public: int equalSubstring(string s, string t, int maxCost) { int sum = 0; int ans = 0; int st = 0; int ed = 0;

jiahonghao2002的博客 219

滑动窗口算法模板

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …如果不存在符合条件的子数组,返回 0。如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。输入:target = 11, nums = [1,1,1,1,1,1,1,1]输入:target = 7, nums = [2,3,1,2,4,3]输入:target = 4, nums = [1,4,4]解释:子数组 [4,3] 是该条件下的长度最小的子数组。

weixin_42031680的博客 216
上一篇: 【动态规划之斜率优化】
下一篇: 暴力搜索——回溯
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值