滑动窗口
438. 找到字符串中所有字母异位词
- 给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。 - 说明:
字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序。 - 示例 1:
输入:
s: "cbaebabacd" p: "abc"
输出:
[0, 6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。
- 题目来源
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Code
class Solution {
public:
//暴力解法会超时
/*
vector<int> findAnagrams(string s, string p) {
if(s.size()<p.size()) return {};
vector<int> result;
string temp;
unordered_map<char,int> p_map,temp_map;
for(auto iter:p) p_map[iter]++;
for (int i = 0; i < s.size() - p.size() + 1; i++) {
int p_size = p.size();
while (p_size--) temp.push_back(s[i++]);
for(auto iter:temp) temp_map[iter]++;
i = i - p.size();
if (p_map==temp_map) result.push_back(i);
temp.clear();
temp_map.clear();
}
return result;
}
*/
//学会使用滑动窗口,注意边界的取舍
vector<int> findAnagrams(string s, string p) {
if(s.size()<p.size()) return {};
vector<int> result;
vector<int> s_statistics(26,0),p_statistics(26,0);
int l=0,r=0;
//初始化值
for(int i=0;i<p.size();i++){
p_statistics[p[i]-'a']++;
s_statistics[s[r++]-'a']++;
}
if(p_statistics==s_statistics) result.push_back(l);
//固定长度的滑动窗口
while(r<s.size()){
s_statistics[s[r++]-'a']++;//窗口右移
s_statistics[s[l++]-'a']--;//保证窗口大小不变
if(p_statistics==s_statistics) result.push_back(l);
}
return result;
}
};