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

14.LeetCode 438 题解:滑动窗口+哈希表找所有字母异位词

目录

一、题目解析

二、讲解算法原理

1. 如何快速判断两个字符串是否是“异位词”?

2. 解决问题:滑动窗口 + 哈希表

三、解决问题(滑动窗口 + 哈希表流程)

四、优化:更新结果的判断条件

五、完整代码(Java)


一、题目解析

题目:438. 找到字符串中所有字母异位词

链接:438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

题目描述:给定两个字符串sp,找到s中所有p的异位词的子串,返回这些子串的起始索引(不考虑答案输出的顺序)。

异位词:由相同字母重新排列形成的字符串(包括相同的字符串)。

示例 1

输入:s = "cbaebabacd",p = "abc"

输出:[0, 6]

解释:起始索引等于 0 的子串是"cba",它是"abc"的异位词;起始索引等于 6 的子串是"bac",它是"abc"的异位词。

示例 2

输入:s = "abab",p = "ab"

输出:[0, 1, 2]

二、讲解算法原理

1. 如何快速判断两个字符串是否是“异位词”?

利用哈希表。例如:

  • 字符串s1 = "aabca":统计每个字符出现次数 →a→3, b→1, c→1(记为hash1)。

  • 字符串s2 = "abaca":统计每个字符出现次数 →a→3, b→1, c→1(记为hash2)。

    hash1hash2完全相同,则两字符串是异位词。

2. 解决问题:滑动窗口 + 哈希表

核心思路:用滑动窗口维护s中与p长度相同的子串,用哈希表统计窗口内字符与p的字符频次,判断是否匹配。

三、解决问题(滑动窗口 + 哈希表流程)

  1. 初始化窗口:left = 0,right = 0

  2. 进窗口:将s[right]加入窗口,更新窗口字符的哈希表(hash2)。

  3. 判断窗口长度:若right - left + 1 > p.length(),则需要出窗口(移除s[left]),更新hash2

  4. 更新结果:检查hash2p的哈希表(hash1)是否匹配,若匹配则记录起始索引left

四、优化:更新结果的判断条件

利用变量count统计窗口中“有效字符”的个数(即窗口内字符频次 ≤p中对应字符频次的字符数量)。

  • 进窗口:进入字符后,若hash2[in] ≤ hash1[in],则count++(说明该字符是“有效”的)。

  • 出窗口:离开字符前,若hash2[out] ≤ hash1[out],则count--(说明该字符离开后,“有效”字符减少)。

  • 更新结果:当count == p.length()时,说明窗口内所有字符都“有效”,即找到异位词,记录left

五、完整代码(Java)

class Solution { public List<Integer> findAnagrams(String ss, String pp) { List<Integer> ret = new ArrayList<Integer>(); char[] s = ss.toCharArray(); char[] p = pp.toCharArray(); int[] hash1 = new int[26]; // 统计字符串 p 中每一个字符出现的个数 for (char ch : p) hash1[ch - 'a']++; int[] hash2 = new int[26]; // 统计窗口中每一个字符出现的个数 int m = p.length; for (int left = 0, right = 0, count = 0; right < s.length; right++) { char in = s[right]; if (++hash2[in - 'a'] <= hash1[in - 'a']) count++; // 进窗口 + 维护 count if (right - left + 1 > m) // 判断窗口长度是否超过 p 的长度 { char out = s[left++]; if (hash2[out - 'a']-- <= hash1[out - 'a']) count--; // 出窗口 + 维护 count } // 更新结果:当 count == m 时,说明窗口内是异位词 if (count == m) ret.add(left); } return ret; } }
http://www.jsqmd.com/news/946864/

相关文章:

  • 基于NodeMCU与IFTTT的Google Assistant语音控制智能开关实现
  • 面试官追问‘背靠背’场景?一个传感器数据采集的实例带你彻底搞懂异步FIFO深度
  • 别再只玩瘦AP了!用Cisco Fat AP在家搭建小型无线实验室(附Packet Tracer配置)
  • 告别卡顿!用CGAL库5分钟搞定3D模型网格优化(附完整C++代码)
  • 终极跨平台Java反编译工具Luyten:Windows、Mac、Linux系统高效适配完整指南
  • 保姆级教程:用JD-GUI和JAD反编译JimuReport 1.7.0源码并成功运行(附常见错误修复)
  • FX3U软元件实战笔记:如何用M8020标志位和高速计数器C235优化设备控制程序
  • Transformers Pipeline:NLP 任务的全面指南
  • WebSocket、HTTPS 与浏览器访问网页全过程
  • SAPscript表单设计避坑指南:从SE71页面布局到ABAP变量传递的常见错误
  • 别再死记硬背公式了!用Python脚本5分钟搞定异步FIFO深度计算(附代码)
  • C语言性能优化封神指南:从CPU缓存到汇编调优,性能直接翻数倍
  • 2026年6月岗位外包公司推荐:TOP5专业评测用工成本控制案例价格 - 品牌推荐
  • 告别Cygwin!用Windows版MRT批量拼接MODIS影像的保姆级教程
  • KeymouseGo:终极鼠标键盘自动化工具完全指南 - 快速解放你的双手!
  • 2026年天津代理记账公司选对=省心 荣天会计值得推荐 - 本地品牌推荐
  • 高效研究周报:信息爆炸时代的知识管理利器
  • 别再死记硬背了!图解upload-labs 20关核心防御与绕过原理(PHP/Windows/Linux环境差异详解)
  • 2026年6月北京管道疏通公司推荐:十大排名家庭防堵塞评测专业价格 - 品牌推荐
  • 微软研究院如何为社交媒体研究设定新标准:从数据、方法到伦理的范式升级
  • 别再瞎调了!手把手教你用手机App和自制工具搞定卫星锅三大角度(附实测避坑)
  • 换SSD后装系统四条实操路径:克隆、PE离线、纯净安装与DISM迁移
  • 从Argparse到Click:我是如何用5个装饰器重构了团队的CLI工具(附代码对比)
  • 10 个能持续产生收入的开源项目
  • 从投稿被拒到秒过格式关:我的Elsevier cas-sc LaTeX模板高效使用心法
  • 不止是RTOS:聊聊Zephyr的安全开发生命周期(SDL)如何为你的物联网设备保驾护航
  • ComfyUI IPAdapter Plus完整指南:快速掌握多图像控制生成技术
  • 量子计算在生物医学中的革命性应用
  • AI模型开源许可证合规性解析与商用边界判定
  • 保姆级教程:给魔百盒CM311-5(GK6323芯片)刷入安卓9 TVBox固件,附固件下载与避坑指南