滑动窗口(一)

简介: 滑动窗口(一)

滑动窗口

什么是滑动窗口算法?通俗的来讲就是 “同向双指针” ,当一组数据的规律含有单调性的时候,就可以使用下面这套逻辑来优化暴力解法。

当两个指针同向移动的时候,类似于一个窗口在滑动。使用于在连续序列里找特殊的子串、子数列、子数组等。

下面将用一道题来解释上面的逻辑。

长度最小的子数组

长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0

定义两个指针 left,right,都从零位置开始,用 sum 记录子数组的和。

第一步:进窗口(sum+=nums [right] ),将第一个值添加到 sum 中。

第二步:判断:sum 是否 大于等于题目要求的 target ,如果符合,就进入循环:更新长度 最小长度 len,让‘窗口’向右划(left左移)!再次进行第二步的判断,当不满足 sum 大于等于 target 这个要求的时候,就让 right++,准备下次的进窗口。

这道题还有一个细节需要注意:需要定义一个 flag 如果 满足过sum大于等于 就要让 flag 的值改变,只要当他满足过的时候,才能返回 len,否则就是序列中没有满足条件的,返回 0。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0, right = 0, n = nums.size();
        int sum = 0;
        int len = nums.size();
        int flag = 0;
        while (right < n)
        {    
            sum += nums[right];
            while(sum >= target)
            {
                flag = 1;
                if (right - left < len) len = right - left + 1;
                sum -= nums[left];
                left++;
            }
            right++;
        }
        if(flag == 1) return len;
        else return 0;
    }
};

无重复字符的最长子串

无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长连续子字符串 的长度。

思路:利用哈希表作为判断字符是否重复的依据,使用滑动窗口更新最长的长度。

因为数据比较少,所以可以直接使用 ASCII 来构建哈希表,将ASCII 当做下标,出现了的话那个位置的数就加1.

判断条件为:hash 表里 right 位置的值大于1,说明有重复的字符进入了哈希表,然后开始出窗口,循环出,直至这个 hash 表里 right 位置的值等于1后,right++,为下一次进窗口做准备。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int left = 0,right = 0,n=s.size();
        int len = 0;
        int hash[128]={0};
        while(right < n)
        {
            hash[s[right]]++;
            while(hash[s[right]]>1)
            {
                hash[s[left++]]--;
            }
            len = max(len, right -left + 1);
            right++;
        }
        return len;
    }
};

最大连续1的个数

最大连续1的个数 III

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k0 ,则返回 数组中连续 1 的最大个数

此题如果采用正常方法的话,将是特别特别难的一道题,所以采用正难则反的思想。

将题目中找反转不大于K个0后的连续1的最大个数,转化为:找最长的子数组,其中这个子数组中 0 的个数不大于 K,利用滑动指针来解决就可以了,判断条件就是子数组中 0 个数小于等于 K,更新的结果就是这个子数组的长度!

class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        //题目转化为在数组中找到一个子数组,里面零的个数小于 K 个
        int left = 0, right = 0, zero = 0;
        int n = nums.size();
        int len = 0;
        while (right < n)
        {
            if(nums[right]==0) zero++;
            while (zero > k)
            {
                if (nums[left] == 0) zero--;
                left++;
            }
            len = max(len, right - left+1);
            right++;
        }
        return len;
    }
};

将 x 减到 0 的最小操作数

将 x 减到 0 的最小操作数

给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。

如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1

依旧是正难则反

将问题转化为:在数组中间找到一个最长的子数组,使它的值恰好等于 sum - x, 当数组中间这个子数组最长时,刚好对应了两边的数(即操作最少),算出除了这个数组外序列剩余的个数,就找到了最小操作数。

相关文章
|
Shell 网络安全 开发工具
Tabby终端工具的配置和使用
Tabby终端工具的配置和使用
9772 0
|
10月前
|
存储 JSON 安全
Go语言切片,使用技巧与避坑指南
Go语言中的切片(Slice)是动态引用数组的高效数据结构,支持扩容与截取。本文从切片基础、常用操作到高级技巧全面解析,涵盖创建方式、`append`扩容机制、共享陷阱及安全复制等内容。通过代码示例详解切片特性,如预分配优化性能、区分`nil`与空切片、处理多维切片等。掌握这些核心知识点,可编写更高效的Go代码。
401 2
|
2月前
|
人工智能 运维 监控
2026年OpenClaw/Clawdbot必装10大Skills指南:从部署到技能精通
在AI Agent技术飞速迭代的2026年,OpenClaw(原Clawdbot)凭借轻量化部署、高自由度扩展的特性,成为个人与企业构建自动化工作流的核心工具。而真正决定OpenClaw能力上限的,并非基础模型本身,而是其开放的Skills(技能系统)——这一插件生态如同给AI助手装上“多功能工具包”,可扩展实时搜索、浏览器自动化、网页部署、性能检测等关键能力,让普通问答助手升级为能执行真实任务的智能工作系统。
6441 15
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
24098 2
|
2月前
|
Linux 虚拟化 iOS开发
VMware Workstation Pro 25H2u1 发布 - 免费桌面虚拟化软件
VMware Workstation Pro 25H2u1 for Windows & Linux - 领先的免费桌面虚拟化软件
3294 0
VMware Workstation Pro 25H2u1 发布 - 免费桌面虚拟化软件
|
11月前
|
设计模式 缓存 算法
Go如何进行高质量编程与性能调优实践
本文介绍了Go语言高质量编程与性能调优的实践方法。高质量编程包括良好的编码习惯(如清晰注释、命名规范)、代码风格与设计(如MVC模式)、简洁明了的代码原则,以及单元测试与代码重构的重要性。性能调优方面,涵盖算法优化、数据结构选择、I/O优化、内存管理、并行与并发处理优化及代码层面的改进。通过这些方法,可有效提升代码质量和系统性能。
224 13
|
SQL 运维 监控
高效定位 Go 应用问题:Go 可观测性功能深度解析
为进一步赋能用户在复杂场景下快速定位与解决问题,我们结合近期发布的一系列全新功能,精心梳理了一套从接入到问题发现、再到问题排查与精准定位的最佳实践指南。
|
NoSQL MongoDB 微服务
微服务2——MongoDB单机部署1——下载安装
本指南介绍在Windows系统上安装和启动MongoDB的步骤。首先,从官网下载适用于32位或64位系统的预编译二进制包,选择稳定版(y为偶数)。解压后创建数据目录`data/db`,可通过命令行参数(如`mongod --dbpath=..\data\db`)或配置文件启动服务。配置文件需注意转义字符与空格使用,支持自定义日志路径、端口等参数。将bin目录加入环境变量可简化启动操作。
401 0
微服务2——MongoDB单机部署1——下载安装
|
存储 安全 Java
Spring Security 入门与详解
Spring Security 是 Spring 框架中的核心安全模块,提供认证、授权及防护功能。本文详解其核心概念,包括认证(Authentication)、授权(Authorization)和过滤器链(Security Filter Chain)。同时,通过代码示例介绍基本配置,如 PasswordEncoder、UserDetailsService 和自定义登录页面等。最后总结常见问题与解决方法,助你快速掌握 Spring Security 的使用与优化。
2805 0
|
JSON Java Go
Go 语言性能优化技巧
在Go语言中优化性能涉及数字字符串转换(如用`strconv.Itoa()`代替`fmt.Sprintf()`)、避免不必要的字符串到字节切片转换、预分配切片容量、使用`strings.Builder`拼接、有效利用并发(`goroutine`和`sync.WaitGroup`)、减少内存分配、对象重用(`sync.Pool`)、无锁编程、I/O缓冲、正则预编译和选择高效的序列化方法。这些策略能显著提升代码执行效率和系统资源利用率。
430 13