0%

find-all-anagrams-in-a-string

Find All Anagrams in a String – LeetCode 438

Problem

Description

Given a string s and a non-empty string p, find all the start indices of p’s anagrams in s.

Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

The order of output does not matter.

Answer

Original

Code

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) {
vector<int> pv(26,0), sv(26,0), res;
if(s.size() < p.size())
return res;
for(int i = 0; i < p.size(); ++i)
{
++pv[p[i]-'a'];
++sv[s[i]-'a'];
}
if(pv == sv)
res.push_back(0);
for(int i = p.size(); i < s.size(); ++i)
{
++sv[s[i]-'a'];
--sv[s[i-p.size()]-'a'];
if(pv == sv)
res.push_back(i-p.size()+1);
}
return res;
}
};

思路

简单的建立一张表来滑动对比。依旧没有漂亮的解决比对的问题。时间复杂度$O(n)$,空间复杂度$O(n)$。
耗时$34$ ms,排名$23.15\%$

Better

思路

这个也是滑动窗口,但是比对的过程设计的更加仔细,开销会小一些。时间复杂度$O(n)$,空间复杂度$O(n)$。
耗时$34$ ms,排名$23.15\%$

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
if (s.empty()) return {};
vector<int> res, m(256, 0);
int left = 0, right = 0, cnt = p.size(), n = s.size();
for (char c : p) ++m[c];
while (right < n) {
if (m[s[right++]]-- >= 1) --cnt;
if (cnt == 0) res.push_back(left);
if (right - left == p.size() && m[s[left++]]++ >= 0) ++cnt;
}
return res;
}
};