跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

滑动窗口算法:查找字符串中的字母异位词

基于滑动窗口技术解决寻找字符串中所有字母异位词的问题。核心在于维护一个固定长度的窗口,利用哈希表统计字符频次,并通过计数变量避免每次遍历对比哈希表。当窗口内有效字符数等于目标字符串长度时,即找到一个异位词。该方法将时间复杂度从暴力解法的 O(N^3) 或 O(N^2) 优化至 O(N),空间复杂度为 O(1)(假设字符集大小固定)。

草莓泡芙发布于 2026/2/8更新于 2026/10/257.2K 浏览
滑动窗口算法:查找字符串中的字母异位词

示例图

1. 核心思路

滑动窗口是解决子串问题的常用技巧。对于寻找字母异位词,关键在于维护一个固定长度的窗口,并高效判断窗口内的字符组成是否与目标字符串一致。

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> result;
        if (s.empty() || p.empty() || s.size() < p.size()) return result;
        
        int len = p.size();
        vector<int> hash(26, 0);
        for (char c : p) hash[c - 'a']++;
        
        int count = 0; // 统计有效字符数
        for (int i = 0; i < len; ++i) {
            if (hash[s[i] - 'a'] > 0) count++;
            hash[s[i] - 'a']--;
        }
        
        if (count == len) result.push_back(0);
        
        for (int i = len; i < s.size(); ++i) {
            // 出窗口
            if (hash[s[i - len] - 'a'] >= 0) count--;
            hash[s[i - len] - 'a']++;
            
            // 进窗口
            if (hash[s[i] - 'a'] > 0) count++;
            hash[s[i] - 'a']--;
            
            if (count == len) result.push_back(i - len + 1);
        }
        return result;
    }
};

2. 知识点导图

文章配图

3. 题目描述

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

要点:

  • 找子串
  • 异位词:相同字母排列组合形成的字符串

怎么快速判断两个字符串是不是异位词?

创建两个哈希表

4. 解题

4.1 暴力解法

  1. 以 p 的长度 n 为单位,暴力枚举 s 中的所有 n 元组。
  2. 把 n 元组扔进哈希表中统计元素及其个数。
  3. 与另一哈希表(统计 p)比对。
    • 时间复杂度 O(N^3),必然超时。

4.2 优化解法

4.2.1 双指针优化

和之前的思路一样,通过同向双指针,把嵌套 for 的 O(N^2) 干成 O(N)。

最终复杂度为 O(N^2):比对哈希表的过程中还有一次遍历还能优化。

4.2.2 计数变量优化

外层循环已经被优化了,我们现在来看内部遍历哈希表的过程能不能优化下,或者说我们换一种方式来维护窗口信息。

现在我来尝试用例子来模拟 hash 统计子串数据:

文章配图

文章配图

文章配图

文章配图

我们在用 hash 统计子串数据的过程中,我们发现:

我们统计的 s 中的数据可以分成两类:有效数据和无效数据

并且我们发现,当有效数据的个数和 hash1 中的数据个数相同,且 L=n 的时候。此时的子串完全符合要求。

因此,我们要做的事就从遍历对比两个哈希表数据变成了统计有效数据的个数。

因此,我们要创建一个 count 变量来统计有效数据的个数,并在窗口中不断维护它。

代码逻辑
  1. 先用 hash1 统计 p 的元素。
  2. 滑动窗口:
    • 进窗口:right 元素进 hash2
    • 判断:L>n
    • 出窗口:判断出的元素是否是有效元素,维护 count
    • 更新信息:L=n,count=p.size();返回 left

5. 总结

通过引入计数变量 count,避免了每次移动窗口后重新遍历哈希表进行比对,将比较操作的时间复杂度从 O(K) 降为 O(1),整体算法时间复杂度优化至 O(N)。

目录

  1. 1. 核心思路
  2. 2. 知识点导图
  3. 3. 题目描述
  4. 怎么快速判断两个字符串是不是异位词?
  5. 创建两个哈希表
  6. 4. 解题
  7. 4.1 暴力解法
  8. 4.2 优化解法
  9. 4.2.1 双指针优化
  10. 4.2.2 计数变量优化
  11. 我们统计的 s 中的数据可以分成两类:有效数据和无效数据
  12. 代码逻辑
  13. 5. 总结

更多推荐文章

查看全部
  • 元气 AI Bot 功能解析:国产 AI 助手的桌面应用实践
  • Android 休眠机制详解
  • GitHub Copilot:Python 开发者的 AI 助手
  • 使用 IDEA 社区版从零开始创建第一个 SpringBoot 程序
  • 牛客 NC221681 dd 爱框框:滑动窗口解法详解
  • 宇树 G1 人形机器人强化学习训练实战指南
  • GitHub Copilot 四种模式区别:Agent、Ask、Edit、Plan
  • Java Map 常用方法与核心实现类深度解析
  • C++ 高效入门:从 C 语言到 C++ 的平滑过渡(一)
  • 2024 年大模型产品经理转行指南:核心技能与学习路径
  • 用于数据增强的十个 Python 库
  • AI 大模型微调与推理实战指南
  • LightRAG:降低 GraphRAG 落地门槛的轻量级检索增强生成框架
  • Python 布尔类型详解:真值、运算与控制流
  • OpenClaw 飞书机器人搭建指南
  • 2025 年睿抗机器人开发者大赛 CAIP-编程技能赛本科组国赛解题报告
  • OpenStack 版本发布周期与系列概览
  • AI 代理工具全景:Claude Code 等六大产品深度解析
  • IO 多路复用 select 接口解析与服务器实战
  • 2026 年 3 月全球 AI 前沿动态:模型、智能体与基础设施

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online