欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > leetcode 438. 找到字符串中所有字母异位词

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

2025/5/23 19:02:34 来源:https://blog.csdn.net/weixin_45524582/article/details/148151357  浏览:    关键词:leetcode 438. 找到字符串中所有字母异位词

这个解题思路的核心是利用固定大小的滑动窗口数组统计字符频率来高效判断子串是否为异位词。以下是详细解释:

1. 核心思路

  • 异位词的定义:两个字符串包含的字符及其数量完全相同,只是顺序可能不同。例如,“abc” 和 “bca” 是异位词。
  • 滑动窗口的适用性:由于异位词的长度必须与原字符串相同,因此可以在 s 中滑动一个长度为 p.size() 的窗口,逐一检查窗口内的字符频率是否与 p 一致。

2. 算法步骤

步骤1:预处理字符频率数组
  • 创建两个长度为 26 的数组(假设只包含小写字母):
    • target[26]:统计 p 中每个字符的出现次数。
    • window[26]:统计当前窗口中每个字符的出现次数。
步骤2:初始化第一个窗口
  • 遍历 s 的前 p.size() 个字符,将字符频率填入 window 数组。
步骤3:滑动窗口并检查匹配
  • 固定窗口大小:窗口始终保持长度为 p.size()
  • 每次滑动
    1. 右移窗口:将右侧新字符加入窗口(更新 window 数组)。
    2. 移出左侧字符:将左侧旧字符移出窗口(更新 window 数组)。
    3. 检查匹配:比较 windowtarget 是否完全相同。若相同,则记录当前窗口的起始位置。

3. 关键优化点

用数组替代哈希表
  • 由于字符集较小(26个小写字母),使用数组比哈希表更高效。数组的随机访问时间复杂度为 O(1),且无需处理哈希冲突。
固定窗口大小
  • 窗口大小始终等于 p.size(),避免了动态调整窗口的复杂性,简化了逻辑。
快速比较数组
  • 直接比较两个数组(window == target)的时间复杂度为 O(26) = O(1),因为数组长度固定。

4. 处理特殊情况

  • s.size() < p.size():直接返回空结果,因为无法构造有效窗口。

5. 复杂度分析

  • 时间复杂度:O(n),其中 n 是 s 的长度。每个字符仅被访问两次(加入窗口和移出窗口)。
  • 空间复杂度:O(1),因为数组大小固定为 26,不随输入长度变化。

6. 示例代码(参考力扣官方题解)

vector<int> findAnagrams(string s, string p) {vector<int> result;if (s.size() < p.size()) return result;vector<int> target(26, 0);vector<int> window(26, 0);// 统计p中字符频率for (char c : p) target[c - 'a']++;// 初始化第一个窗口for (int i = 0; i < p.size(); i++) {window[s[i] - 'a']++;}// 检查第一个窗口if (window == target) result.push_back(0);// 滑动窗口for (int i = p.size(); i < s.size(); i++) {// 移出左侧字符window[s[i - p.size()] - 'a']--;// 移入右侧字符window[s[i] - 'a']++;// 检查当前窗口if (window == target) result.push_back(i - p.size() + 1);}return result;
}

7. 与你的测试用例的关系

在你的测试用例中,sp 都很长,但主要由 a 组成。上述算法通过固定窗口大小和数组统计,能高效处理这种情况,避免了频繁哈希表操作的开销。每次滑动窗口只需 O(1) 时间更新频率并比较数组,因此即使字符串很长,也能快速找到所有异位词位置。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词