news 2026/8/3 14:25:18

【优选算法】滑动窗口专项:1.串联所有单词的子串 2.最小覆盖子串

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【优选算法】滑动窗口专项:1.串联所有单词的子串 2.最小覆盖子串

🔥小龙报:个人主页
🎬作者简介:C++研发,嵌入式,机器人,AI等方向学习者
❄️个人专栏:《优选算法》
永远相信美好的事情即将发生

文章目录

  • 前言
  • 一、串联所有单词的子串
    • 1.1题目
    • 1.2 算法原理
      • 1.2.1 算法思路
    • 1.3 代码
  • 二、最小覆盖子串
    • 2.1 题目
    • 2.2 算法原理
      • 2.2.1 算法思路
      • 2.2.2 算法流程
    • 2.3 代码
  • 总结与每日励志

前言

滑动窗口是字符串高频考点,哈希表则是窗口匹配的核心辅助工具。本文选取两道典型 LeetCode 例题展开讲解,一道以单词为匹配单元,一道以单个字符为匹配单元,覆盖异位词、最小覆盖子串两类经典场景。文中拆解算法底层逻辑,给出可直接提交的 C++ 代码,统一梳理双指针扩张、收缩窗口的完整流程,帮你吃透滑动窗口通用解题模板,快速掌握字符串匹配类题目的通用思路。


一、串联所有单词的子串

1.1题目

链接:串联所有单词的子串

1.2 算法原理

核心思想:滑动窗口 + 哈希表

1.2.1 算法思路

如果我们把每一个单词看成一个一个字母,问题就变成了找到「字符串中所有的字母异位词」。无非就是之前处理的对象是一个一个的字符,我们这里处理的对象是一个一个的单词。

1.3 代码

classSolution{public:vector<int>findSubstring(strings,vector<string>&words){vector<int>ret;//存储结果unordered_map<string,int>h1;//统计words的for(auto&a:words)h1[a]++;intm=words.size(),n=s.size();intlen=words[0].size();for(inti=0;i<len;i++){intcount=0;//统计有效unordered_map<string,int>h2;for(intl=i,r=i;r+len<=n;r+=len){stringin=s.substr(r,len);h2[in]++;if(h2[in]<=h1[in])count++;if(r-l+1>len*m){stringout=s.substr(l,len);if(h2[out]--<=h1[out])count--;l+=len;}if(count==m)ret.push_back(l);}}returnret;}};

时间复杂度: O(n)

二、最小覆盖子串

2.1 题目

链接:最小覆盖子串

2.2 算法原理

核心思想滑动窗口 + 哈希表

  • 研究对象是连续的区间,因此可以尝试使用滑动窗口的思想来解决。
  • 如何判断当前窗口内的所有字符是符合要求的呢?

我们可以使用两个哈希表,其中一个将目标串的信息统计起来,另一个哈希表动态的维护窗口内字符串的信息。

当动态哈希表中包含目标串中所有的字符,并且对应的个数都不小于目标串的哈希表中各个字符的个数,那么当前的窗口就是一种可行的方案。

因为数据范围有限,可以使用数组来模拟哈希表

2.2.1 算法思路

a. 定义两个全局的哈希表:1 号哈希表hash1用来记录子串的信息,2 号哈希表hash2用来记录目标串 t 的信息;

b. 实现一个接口函数,判断当前窗口是否满足要求:
i. 遍历两个哈希表中对应位置的元素:
- 如果 t 中某个字符的数量大于窗口中字符的数量,也就是 2 号哈希表某个位置大于 1 号哈希表。说明不匹配,返回false
- 如果全都匹配,返回true

2.2.2 算法流程

主函数中:

a. 先将t的信息放入 2 号哈希表中;
b. 初始化一些变量:左右指针:left = 0, right = 0;目标子串的长度:len = INT_MAX;目标子串的起始位置:retleft;(通过目标子串的起始位置和长度,我们就能找到结果)
c. 当right小于字符串s的长度时,一直下列循环:
i. 将当前遍历到的元素扔进 1 号哈希表中;
ii. 检测当前窗口是否满足条件:
如果满足条件:
判断当前窗口是否变小。如果变小:更新长度len,以及字符串的起始位置retleft
-判断完毕后,将左侧元素滑出窗口,顺便更新 1 号哈希表;
重复上面两个过程,直到窗口不满足条件;
iii.right++,遍历下一个元素;
d. 判断len的长度是否等于INT_MAX
i. 如果相等,说明没有匹配,返回空串;
ii. 如果不相等,说明匹配,返回s中从retleft位置往后len长度的字符串。

    2.3 代码

    classSolution{public:stringminWindow(string s,string t){inthash1[128]={0};//统计t的每个字符出现次数inthash2[128]={0};//统计s的每个字符出现次数intkind=0;//t中hash1有效字符出现的种类for(autoa:t){if(hash1[a]++==0)kind++;}intl=0,r=0,n=s.size();intcount=0;//统计s中有效字符的种类intret=1e6+10,begin=-1;while(r<n){charin=s[r];if(++hash2[in]==hash1[in])//进窗口 + 有效字符种类count++;while(count==kind)//判断{if(ret>r-l+1)//更新结果{ret=r-l+1;begin=l;}charout=s[l++];if(hash2[out]--==hash1[out])count--;}r++;}if(begin==-1)return"";elsereturns.substr(begin,ret);}};

    时间复杂度: O(N)

    总结与每日励志

    两道例题均采用滑动窗口搭配哈希表的核心框架,仅匹配粒度存在差异:最小覆盖子串以单个字符为单位遍历,串联单词子串按单词长度分多轮遍历。二者都通过哈希表统计目标元素频次,用有效计数简化窗口合法性判断,避免重复遍历哈希表,把时间复杂度压缩至线性。掌握这套模板可解决绝大多数连续子串匹配题,日常刷题可复用双指针扩张收缩逻辑,高效处理各类字符串窗口类算法场景。

    版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
    网站建设 2026/8/3 14:24:53

    海康威视MP4录像Web播放兼容性问题与FFmpeg标准化解决方案

    1. 问题缘起&#xff1a;一个看似简单的需求&#xff0c;为何如此棘手&#xff1f; 最近在做一个安防监控相关的项目&#xff0c;需要把海康威视摄像头本地存储的录像文件&#xff0c;在Web页面上进行回放。这听起来是个很基础的功能&#xff0c;对吧&#xff1f;不就是把MP4文…

    作者头像 李华
    网站建设 2026/8/3 14:24:43

    从GR00T模型到LeRobot机械臂:Jetson AGX Thor上的AI机器人部署实战

    1. 项目概述&#xff1a;从开源模型到实体机械臂的最后一公里最近在折腾一个挺有意思的项目&#xff0c;核心目标是把一个名为 GR00T N1.5 的通用机器人基础模型&#xff0c;微调后部署到一台具体的 LeRobot SO-101 机械臂上&#xff0c;并且让它在 Jetson AGX Thor 这个边缘计…

    作者头像 李华
    网站建设 2026/8/3 14:15:39

    线缆选型全攻略:从电气参数到场景实战,构建稳定连接基石

    1. 从“能用”到“好用”&#xff1a;线缆选择的底层逻辑每次看到有人随便拿根线就给设备插上&#xff0c;或者因为一根线导致设备工作不稳定、充电慢甚至损坏&#xff0c;我都觉得挺可惜的。线缆&#xff0c;这个连接数字世界与物理世界的“血管”&#xff0c;其重要性常常被严…

    作者头像 李华
    网站建设 2026/8/3 14:12:05

    Python接单实战指南:从零到一实现技术变现

    昨天下午&#xff0c;我收到了一笔468元的转账&#xff0c;项目是帮一个电商团队写一个自动处理商品图片尺寸和重命名的Python脚本。这不是什么大项目&#xff0c;但整个过程——从沟通需求、报价、开发到交付——只用了不到4个小时。这种“在家干活&#xff0c;即时变现”的感…

    作者头像 李华