news 2026/9/3 2:37:05

滑动窗口-----找到所有字母异位词

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
滑动窗口-----找到所有字母异位词

🔥个人主页:Milestone-里程碑

❄️个人专栏: <<力扣hot100>> <<C++>><<Linux>>

<<Git>><<MySQL>>

🌟心向往之行必能至

题目解读

给定两个字符串sp,我们需要在s中找到所有是p字母异位词的子串,并返回这些子串的起始索引。

  • 字母异位词:指由相同字母重排列形成的字符串,比如"abc""cba"就是一对异位词。
  • 核心思路:因为异位词的字符组成完全相同,所以我们可以通过比较字符频率来判断两个字符串是否为异位词。

算法思路:滑动窗口 + 字符计数

这道题最优雅的解法就是滑动窗口,它能让我们在O(n)的时间复杂度内解决问题,具体步骤如下:

  1. 初始化字符计数数组

    • 先统计字符串p中每个字符的出现次数,存入数组ch(因为是小写字母,数组大小设为 26 即可)。
    • 这个数组就像一个 “字符指纹”,代表了p的字符组成。
  2. 滑动窗口遍历s

    • right指针作为窗口的右边界,每次向右移动时,就把当前字符在ch中的计数减 1。
    • 如果某个字符的计数变成负数,说明它在当前窗口中的出现次数超过了p中的次数,此时需要移动左指针left,并把移出窗口的字符计数加 1,直到所有字符的计数都非负。
  3. 检查窗口是否有效

    • 当窗口的长度(right - left + 1)恰好等于p的长度时,说明当前窗口内的字符频率和p完全一致,这就是一个异位词。
    • 此时把左指针left加入结果列表即可。

完整代码实现

cpp

class Solution { public: vector<int> findAnagrams(string s, string p) { vector<int> res; int ch[26] = {0}; // 统计 p 中每个字符的出现次数 for (int i = 0; i < p.size(); ++i) { ch[p[i] - 'a']++; } int left = 0; for (int right = 0; right < s.size(); ++right) { int c = s[right] - 'a'; ch[c]--; // 右指针字符进入窗口 // 如果当前字符计数为负,说明需要移动左指针 while (ch[c] < 0) { ch[s[left] - 'a']++; left++; } // 窗口长度等于 p 的长度时,记录起始索引 if (right - left + 1 == p.size()) { res.push_back(left); } } return res; } };

代码解析

  • 字符计数数组ch[26]用来记录每个字符的出现次数,通过字符 - 'a'可以把字符映射到 0-25 的索引,非常高效。
  • 右指针扩张:每次右指针移动,就将对应字符的计数减 1,代表该字符进入了当前窗口。
  • 左指针收缩:当某个字符的计数为负时,说明它在窗口中出现过多,需要移动左指针,把移出窗口的字符计数加 1,直到窗口内的字符计数都合法。
  • 有效窗口判断:当窗口长度等于p的长度时,说明窗口内的字符频率和p完全一致,此时左指针就是一个有效的起始索引。

复杂度分析

  • 时间复杂度O(n + m),其中ns的长度,mp的长度。我们只需要遍历sp各一次,滑动窗口的每个元素最多被访问两次(一次被右指针加入,一次被左指针移出)。
  • 空间复杂度O(1),因为我们只使用了一个大小为 26 的数组来记录字符计数,空间开销是固定的。

总结

这道题是滑动窗口算法的典型应用,核心在于利用字符计数来维护窗口的有效性。只要掌握了滑动窗口的 “扩张 - 收缩 - 验证” 思路,这类子串匹配问题就能迎刃而解。

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

从Clawdbot到Moltbook:Agent社会化进程

文章目录 1、前言2、从 Clawdbot 到 OpenClaw&#xff1a;一段改名背后的技术演进2.1 三次改名的故事2.1.1 Clawdbot&#xff1a;起源2.1.2 Moltbot&#xff1a;被迫改名2.1.3 OpenClaw&#xff1a;开源品牌重塑 2.2 技术栈的演进2.3 Peter Steinberger 的设计哲学演变 3、Molt…

作者头像 李华
网站建设 2026/9/3 0:21:28

行转列,根据未知逗号分割——Mysql版

SELECT PK_ID, SJKZRZJLX, SJKZRZJDM FROM BFD.bfd_ftykhx WHERE DATA_DT 2026-01-31AND PK_ID IN (-- 第一步&#xff0c;计算每条记录的拆分数量SELECT T1.PK_ID/*,t1.SJKZRZJDM AS 原始字符串_JDM,t1.SJKZRZJLX …

作者头像 李华
网站建设 2026/9/2 21:50:33

<Linux基础11集>电流+二极管+晶体管+存储器

零 感觉上一集写的不太好,不清晰,没有用自己的话描述 再来一遍 物质的组成 原子(不带电)包括 原子核 和 核外电子(带负电) 原子核包括 质子(带正电) 和 中子 (质子所带的正电量核外电子所带的负电量) 电流的形成 自由电子定向移动形成电流 导体导电的原因 部分电子可以…

作者头像 李华
网站建设 2026/9/2 22:45:22

前后端分离失物招领平台系统|SpringBoot+Vue+MyBatis+MySQL完整源码+部署教程

摘要 随着城市化进程的加快和人口流动性的增强&#xff0c;日常生活中物品遗失的现象日益频繁&#xff0c;传统的失物招领方式效率低下且信息传播范围有限。为解决这一问题&#xff0c;基于前后端分离架构的失物招领平台系统应运而生。该系统通过互联网技术整合失物信息&#…

作者头像 李华
网站建设 2026/9/2 21:52:32

基于Android手机平台的求职招聘 开题报告

目录 研究背景与意义国内外研究现状研究内容技术路线创新点预期成果进度安排 项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 研究背景与意义 随着移动互联网普及&#xff0c;求职招聘逐渐从PC端转向移动…

作者头像 李华
网站建设 2026/9/2 23:29:19

基于Android校园新闻APP开发的设计 开题报告

目录 研究背景与意义目标与功能设计技术选型创新点预期成果进度计划 项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 研究背景与意义 随着移动互联网的普及&#xff0c;校园信息传递效率成为师生关注的焦…

作者头像 李华