找到字符串中所有字母异位词
题目描述
给定两个字符串 s 和 p,找到 s 中所有 p 的异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
示例 1:
- 输入:
s = "cbaebabacd", p = "abc" - 输出:
[0,6] - 解释:
- 起始索引等于 0 的子串是
"cba",它是"abc"的异位词。 - 起始索引等于 6 的子串是
"bac",它是"abc"的异位词。
- 起始索引等于 0 的子串是
示例 2:
- 输入:
s = "abab", p = "ab" - 输出:
[0,1,2] - 解释:
- 起始索引等于 0 的子串是
"ab",它是"ab"的异位词。 - 起始索引等于 1 的子串是
"ba",它是"ab"的异位词。 - 起始索引等于 2 的子串是
"ab",它是"ab"的异位词。
- 起始索引等于 0 的子串是
提示:
1 <= s.length, p.length <= 3 * 10^4s和p仅包含小写字母
解题思路
- 滑动窗口法
在这道题中,我们需要在字符串 s 中找到所有与 p 的异位词匹配的子串。异位词的定义是两个字符串包含相同字符,且每个字符的出现次数相同,因此可以通过计数匹配来判断。
为了解决这个问题,我们可以使用滑动窗口法,窗口的大小与字符串 p 的长度相同。我们通过两个指针(左右指针)来控制窗口,并逐步调整窗口的内容,检查当前窗口是否是 p 的异位词。
- 使用字符计数
- 我们可以用一个固定大小为26的数组
vp来记录字符串p中每个字符的出现频率。 - 同样,我们使用一个大小为26的数组
vs来记录当前窗口中字符的出现频率。 - 每次滑动窗口时,我们调整窗口的右边界
r,并扩展窗口的大小。如果当前窗口大小等于p的长度,我们就比较vs和vp,如果相同,则说明找到了一个异位词。
- 优化滑动窗口
- 每次右边界
r向右滑动时,我们将新字符加入窗口并更新频率。 - 每当窗口大小超过
p的长度时,我们就缩小窗口,移动左边界l,并更新频率,保持窗口大小为p的长度。
代码实现
C++版本代码实现:
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ans;
vector<int> vp(26); // 用于记录 p 字符出现频率
vector<int> vs(26); // 用于记录 s 中当前窗口的字符出现频率
// 填充 p 字符出现频率
for (auto pp : p) {
++vp[pp - 'a'];
}
int l = 0, r = 0;
int ns = s.size();
int np = p.size();
// 滑动窗口
while (r < ns) {

最低0.47元/天 解锁文章
1204

被折叠的 条评论
为什么被折叠?



