给定两个字符串 s
和 p
,找到 s
中所有 p
的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
解法思路:
1.
// 判断字符相等,其实就是给定一个定长的窗口去滑动查找子串,为了便于判断将p 与窗口中的子串进行排序,如果相等则是
// 将窗口的左边界加入
这种解法会有时间复杂度超标的问题吗,但是这个思路也是一种不错的解法
2.
本题维护长为n的子串s 的每种字母的出现次数。如果s 的每种字母的出现次数,和p的每种字母的出现次数都相同,那么s 是p的异位词,把s 左端点下标加入答案。
class Solution {
public:vector<int> findAnagrams(string s, string p) {// // 判断字符相等,其实就是给定一个定长的窗口去滑动查找子串,为了便于判断将p 与窗口中的子串进行排序,如果相等则是// // 将窗口的左边界加入// int dis = p.length();// sort(p.begin(), p.end());// vector<int> result;// if(p.length() < s.length()){// for (int left = 0; left <= s.length() - dis; ++left) {// string sub_str = s.substr(left, dis);// sort(sub_str.begin(), sub_str.end());// if (sub_str == p) {// result.push_back(left);// }// }// }// return result;vector<int> ans;array<int, 26> cnt_p{}; // 统计 p 的每种字母的出现次数array<int, 26> cnt_s{}; // 统计 s 的长为 p.length() 的子串 s' 的每种字母的出现次数for (char c : p) {cnt_p[c - 'a']++;}for (int right = 0; right < s.length(); right++) {cnt_s[s[right] - 'a']++; // 右端点字母进入窗口int left = right - p.length() + 1;if (left < 0) { // 窗口长度不足 p.length()continue;}if (cnt_s == cnt_p) { // s' 和 p 的每种字母的出现次数都相同ans.push_back(left); // s' 左端点下标加入答案}cnt_s[s[left] - 'a']--; // 左端点字母离开窗口}return ans;}};