抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

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


思路

  • 与 L49 一致,但超出时间限制。

  • 滑动窗口,固定一段长度,在前进的时候只要左边的字母数量自减,右边的字母数量自加即可,与刚开始的思路优化的是减少了每次都需要进行 key 的排序。实际上也是对哈希表的键的取值的优化。

学习点

  • 构建哈希表的键的取值,滑动窗口在移动的同时只需要两端的字母的数量自减或自加即可,大大节省时间开销。

代码

超出时间限制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
if (s.length() < p.length())
{
return {};
}
int len = p.length();
// unordered_map
// key(string). value(index)
unordered_map<string, vector<int>> um;
// 遍历 s
for (int i = 0; i < s.length(); i++)
{
string key = s.substr(i, len);
sort(key.begin(), key.end());
um[key].emplace_back(i);
}
// 找 p 对应的键值
sort(p.begin(), p.end());
return um[p];
}
};

滑动窗口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
int s_len = s.length();
int p_len = p.length();
if (s_len < p_len)
return {};
// 滑动窗口 + 哈希表
vector<int> s_counts(26, 0);
vector<int> p_counts(26, 0);
// 存储 indices
vector<int> ans;
// 初始化
for (int i = 0; i < p_len; ++i)
{
++s_counts[s[i] - 'a'];
++p_counts[p[i] - 'a'];
}
// 滑动窗口遍历 s
for (int i = 0; i < s_len - p_len; ++i)
{
// 如果哈希数组相同
if (s_counts == p_counts)
ans.emplace_back(i);
// 不相同,滑动窗口前进,前面的自减,后面的自加
--s_counts[s[i] - 'a'];
++s_counts[s[i + p_len] - 'a'];
}

// 最后再比较一次,如果哈希数组相同
if (s_counts == p_counts)
ans.emplace_back(s_len - p_len);

return ans;
}
};