当前位置: 首页 > news >正文

【算法题】滑动窗口(一)

滑动窗口是处理子串/子数组问题的经典双指针技巧,核心是通过维护一个“窗口”(左右指针界定的区间),动态调整窗口范围来满足题目条件,从而高效求解问题。

一、无重复字符的最长子串

题目描述:
给定一个字符串s,找出其中不含有重复字符的最长子串的长度。

示例

  • 输入:s = "abcabcbb",输出:3(最长子串为"abc"
  • 输入:s = "bbbbb",输出:1(最长子串为"b"

解题思路:
用滑动窗口维护“无重复字符的子串”,配合哈希数组记录字符出现次数:

  1. 定义窗口左右指针leftright,哈希数组hash[128]统计窗口内字符出现次数。
  2. 右指针right遍历字符串,将当前字符加入窗口并更新出现次数。
  3. 若当前字符出现次数超过1(窗口内有重复),移动左指针缩小窗口,直到无重复。
  4. 每次调整后,更新最长子串长度。

完整代码:

classSolution{public:intlengthOfLongestSubstring(string s){inthash[128]={0};intret=0;for(intleft=0,right=0;right<s.size();right++){hash[s[right]]++;while(hash[s[right]]>1){hash[s[left++]]--;}ret=max(ret,right-left+1);}returnret;}};

复杂度分析:

  • 时间复杂度:O(n)O(n)O(n),每个字符最多被左右指针各遍历一次。
  • 空间复杂度:O(1)O(1)O(1),哈希数组大小固定(128个ASCII字符)。

二、长度最小的子数组

题目描述:
给定含n个正整数的数组和正整数target,找出总和≥target的长度最小的子数组,返回其长度;若不存在则返回0

示例

  • 输入:target = 7, nums = [2,3,1,2,4,3],输出:2(子数组[4,3]

解题思路:
用滑动窗口维护“总和≥target的子数组”,动态缩小窗口找最小长度:

  1. 定义窗口左右指针leftright,变量sum记录窗口内元素和。
  2. 右指针right遍历数组,累加元素和到sum
  3. sum ≥ target,尝试移动左指针缩小窗口(同时更新最小长度),直到sum < target
  4. 遍历结束后,若未找到符合条件的子数组则返回0

完整代码:

classSolution{public:intminSubArrayLen(inttarget,vector<int>&nums){intsum=0,len=INT_MAX;for(intleft=0,right=0;right<nums.size();right++){sum+=nums[right];while(sum>=target){len=min(len,right-left+1);sum-=nums[left++];}}returnlen==INT_MAX?0:len;}};

复杂度分析:

  • 时间复杂度:O(n)O(n)O(n),每个元素最多被左右指针各遍历一次。
  • 空间复杂度:O(1)O(1)O(1),仅用常数级额外变量。

三、最大连续1的个数 III

题目描述:
给定二进制数组nums和整数k,最多可以翻转k0,返回操作后数组中连续1的最大个数。

示例

  • 输入:nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2,输出:6(翻转后最长子数组为[1,1,1,0,0,1,1,1,1,1]

解题思路:
用滑动窗口维护“最多包含k0的子数组”(即允许翻转k0后的连续1区间):

  1. 定义窗口左右指针leftright,变量zeros统计窗口内0的个数。
  2. 右指针right遍历数组,遇到0zeros++
  3. zeros > k,移动左指针缩小窗口,直到zeros ≤ k
  4. 每次调整后,更新最长子数组长度。

完整代码:

classSolution{public:intlongestOnes(vector<int>&nums,intk){intret=0;for(intleft=0,right=0,zeros=0;right<nums.size();right++){if(nums[right]==0)zeros++;while(zeros>k){if(nums[left++]==0)zeros--;}ret=max(ret,right-left+1);}returnret;}};

复杂度分析:

  • 时间复杂度:O(n)O(n)O(n),每个元素最多被左右指针各遍历一次。
  • 空间复杂度:O(1)O(1)O(1),仅用常数级额外变量。

四、将x减到0的最小操作数

题目描述:
给定整数数组nums和整数x,每次操作移除数组最左或最右元素并从x中减去该元素值,要求将x恰好减到0,返回最小操作数;否则返回-1

示例

  • 输入:nums = [1,1,4,2,3], x = 5,输出:2(移除后两个元素2+3=5

解题思路:
转化问题:“最小操作数”等价于“数组中最长的、和为sum(nums)-x的子数组”(因为移除的元素是数组两端,剩余的中间子数组和为sum-x)。

  1. 计算数组总和sum,目标子数组和为target = sum - x(若target < 0,直接返回-1)。
  2. 用滑动窗口找最长的、和为target的子数组。
  3. 若找到该子数组,最小操作数为数组长度 - 子数组长度;否则返回-1

完整代码:

classSolution{public:intminOperations(vector<int>&nums,intx){intsum=0;for(auton:nums)sum+=n;inttarget=sum-x;if(target<0)return-1;intret=-1;for(intleft=0,right=0,tmp=0;right<nums.size();right++){tmp+=nums[right];while(tmp>target)tmp-=nums[left++];if(tmp==target)ret=max(ret,right-left+1);}returnret==-1?-1:nums.size()-ret;}};

复杂度分析:

  • 时间复杂度:O(n)O(n)O(n),每个元素最多被左右指针各遍历一次。
  • 空间复杂度:O(1)O(1)O(1),仅用常数级额外变量。
http://www.cnnetsun.cn/news/27248.html

相关文章:

  • 常见报错org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): org.example.dem
  • 甲骨文AI投资支出激增致股价创24年最大跌幅
  • TinyMCE4粘贴word超链接自动解析域名
  • TinyMCE6处理微信公众号音频视频嵌入
  • 昇腾 Ascend 自定义算子开发全攻略:从 TBE DSL 到 AICPU,打通 AI 加速最后一公里
  • 当电机开始“唱歌“:NVH工程师的降噪日常
  • AI界的“经济适用男“!80亿参数小模型完胜GPT-5,成本降低70%,CSDN程序员必藏的智能调度方案
  • FPGA教程系列-Vivado Aurora 8B/10B 例程解读
  • 227827827
  • MCU的启动流程你了解么?
  • 逻辑回归(Logistic Regression)进行多分类的实战
  • RNN(循环神经网络)原理
  • 人机协同重构创作生态——生成式AI赋能内容产业的变革与思考
  • Java 小白求职者在互联网大厂的面试实录:从 Spring Boot 到微服务架构
  • V助手舆情分析智能体:重塑舆情分析,从“人找信息”到“信息为人”
  • 连接2026:十款远程控制软件真实力横评与选择指南
  • 计算机毕业设计springboot基于Spark++Vue.js的学生管理系统 Spark+Vue 高校学生综合信息管理平台 基于 SpringBoot+Spark+Vue 的全链路学生事务中心
  • JavaScript 集合操作的哈希碰撞:攻击者如何利用特殊 Key 导致 Map/Set 性能降级到 O(N)
  • 为什么 C盘空间会莫名其妙减少(即使没装新软件)?
  • 17、深入理解 Linux 文件系统机制与结构
  • 29、Linux 软件使用与故障排除指南
  • 从入门到转行:网络安全自学与跳槽的终极建议
  • 网络安全小白自学之路,别拜师了,求人不如求己_网络安全小白怎么自学
  • 从系统运维到网络安全工程师,8个月转行真实经验分享!
  • 算法系列(Algorithm)- 快速排序
  • RobotStudio2025全功能授权
  • IsaacLab中UR机械臂与Robotiq夹爪的5大配置难点与解决方案
  • cmark Markdown解析器终极指南:从入门到精通
  • 4-bit量化FLUX模型:让专业AI绘图走进寻常百姓家
  • Excel VBA快速入门:7天从零到精通终极指南