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

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

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

  • 题目详情
  • 问题分析
  • 核心思路:滑动窗口
  • 方法一:固定窗口比较法
    • 复杂度分析:
  • 方法二:计数差分法(优化版)
    • 优化原理
  • 方法三:滑动窗口模板(通用解法)
  • 关键点与技巧
  • 性能对比
  • 总结

题目详情

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

问题分析

字母异位词的关键特征是:

字符组成完全相同(字符种类及每个字符的出现次数相同)

字符顺序可以不同

因此,判断两个字符串是否为字母异位词,可以转化为判断它们字符频率分布是否相同。

核心思路:滑动窗口

由于我们要在字符串 s 中寻找与 p 长度相同的异位词子串,可以使用固定大小的滑动窗口来遍历 s,窗口大小即为 p 的长度。然后比较窗口内字符的频率分布与 p 的频率分布是否一致。

方法一:固定窗口比较法

最直接的思路是每次移动窗口后,都比较窗口内字符频率与 p 的字符频率。

public List<Integer> findAnagrams(String s, String p) {List<Integer> result = new ArrayList<>();if (s.length() < p.length()) return result;int[] pCount = new int[26];int[] sCount = new int[26];// 统计p的字符频率,并初始化第一个窗口for (int i = 0; i < p.length(); i++) {pCount[p.charAt(i) - 'a']++;sCount[s.charAt(i) - 'a']++;}// 检查第一个窗口if (Arrays.equals(pCount, sCount)) {result.add(0);}// 滑动窗口:每次向右移动一位for (int i = 0; i < s.length() - p.length(); i++) {// 移除左边界字符sCount[s.charAt(i) - 'a']--;// 添加右边界字符sCount[s.charAt(i + p.length()) - 'a']++;// 检查当前窗口if (Arrays.equals(pCount, sCount)) {result.add(i + 1);}}return result;
}

复杂度分析:

时间复杂度:O(n × 26),其中 n 是字符串 s 的长度,每次比较数组需要 O(26) 时间

空间复杂度:O(26),使用固定大小的数组

方法二:计数差分法(优化版)

我们可以通过维护一个 count 变量来优化判断过程,避免每次都比较整个数组。

public List<Integer> findAnagrams(String s, String p) {List<Integer> result = new ArrayList<>();if (s.length() < p.length()) return result;int[] count = new int[26];// 初始化p的字符统计for (char c : p.toCharArray()) {count[c - 'a']++;}int left = 0, right = 0;int needToMatch = p.length();while (right < s.length()) {// 右指针字符进入窗口char rightChar = s.charAt(right);if (count[rightChar - 'a'] > 0) {needToMatch--;}count[rightChar - 'a']--;right++;// 当窗口大小等于p长度时,检查结果if (right - left == p.length()) {if (needToMatch == 0) {result.add(left);}// 左指针字符移出窗口char leftChar = s.charAt(left);if (count[leftChar - 'a'] >= 0) {needToMatch++;}count[leftChar - 'a']++;left++;}}return result;
}

优化原理

count 数组记录当前窗口中字符与 p 中字符的差值

needToMatch 跟踪还需匹配的字符总数

当 needToMatch == 0 时,说明窗口内字符与 p 完全匹配

方法三:滑动窗口模板(通用解法)

这是一种更通用的滑动窗口解法,使用 valid 变量来跟踪已匹配的字符种类数。

public List<Integer> findAnagrams(String s, String p) {List<Integer> result = new ArrayList<>();Map<Character, Integer> need = new HashMap<>();Map<Character, Integer> window = new HashMap<>();// 初始化need映射for (char c : p.toCharArray()) {need.put(c, need.getOrDefault(c, 0) + 1);}int left = 0, right = 0;int valid = 0;while (right < s.length()) {// 扩大右边界char rightChar = s.charAt(right);right++;if (need.containsKey(rightChar)) {window.put(rightChar, window.getOrDefault(rightChar, 0) + 1);if (window.get(rightChar).equals(need.get(rightChar))) {valid++;}}// 当窗口大小达到p长度时,收缩左边界while (right - left >= p.length()) {// 检查是否找到异位词if (valid == need.size()) {result.add(left);}char leftChar = s.charAt(left);left++;if (need.containsKey(leftChar)) {if (window.get(leftChar).equals(need.get(leftChar))) {valid--;}window.put(leftChar, window.get(leftChar) - 1);}}}return result;
}

关键点与技巧

窗口大小固定:窗口大小始终为 p.length(),每次移动只需考虑进出的两个字符

字符频率统计:使用长度为26的数组统计小写字母频率,比HashMap更高效

优化判断:通过 count 或 valid 变量避免全数组比较,提升效率

边界处理:当 s.length() < p.length() 时直接返回空列表

性能对比

在这里插入图片描述

总结

滑动窗口是解决子串搜索问题的利器。对于字母异位词问题,关键是抓住字符频率一致性这一特征,通过维护窗口内字符频率来高效判断。

对于此题,推荐使用计数差分法,它在实现复杂度和性能之间取得了良好平衡。理解并掌握这种滑动窗口的优化技巧,对解决类似的字符串搜索问题大有裨益。

http://www.dtcms.com/a/552790.html

相关文章:

  • 站内推广和站外推广的区别wordpress采集生成用户插件
  • 高清的网站制作iis7.0搭建网站
  • 使用 Docker Compose 部署 Spring Boot 应用:SmartAdmin 实战指南
  • 徐州建设企业网站网站建设与网站制作
  • 拆解ASP.NET MVC 视图模型:为 View 量身定制的 “数据小票“
  • 使用Docker搭建DOClever接口管理平台
  • 2025年10月个人工作生活总结
  • 金仓售后服务体系:构建高可用数据库运维新范式
  • 融入现代消费生活 浦发故宫文化主题卡的传承与创新
  • Android Studio Narwhal 4:创建空应用报错 —— AAPT2 process unexpectedly exit 的排查与解决
  • 九寨:在山水间触摸生活的诗意
  • C++(23):延长for循环临时变量生命期
  • Android Studio gradle下载失败报错
  • 贵州 做企业网站的流程58同城最新消息招聘
  • Kubernetes 双层 Nginx 容器环境下的 CORS 问题及解决方案(极端情况)
  • Kimi发布新一代注意力架构!线性注意力实现75% KV缓存减少、6倍解码速度提升
  • 做电子商务系统网站建设wordpress图片加水印
  • 电机参数标幺化与定点计算在整数MCU上的实现
  • Rust开发之错误处理与日志记录结合(log crate使用)
  • 2025年11月1日(星期六)骑行笔架山
  • opencv 学习: 03 初识 cv:Mat
  • 数据结构(c++版):邻接矩阵的实现
  • 在华为TaiShan 200系列服务器基于CentOS 7.6/7.7创建虚拟机
  • Parallels Desktop 26.1.1 for Mac 秋叶QiuChenly中文解锁直装版,最好用的macOS虚拟机
  • Linux chmod权限速成指南
  • 企业网站建设市场的另一面写字就能赚钱做网站
  • 【已解决】解决CondaVerificationError:PyTorch安装包损坏问题
  • UI引擎里AceAbility::OnStart函数1
  • 卸载工具uninstall tool下载安装教程(附安装包)绿色版
  • Bug: 升级内核后有线网络无法使用