大学做网站长沙seo免费诊断
给定两个字符串 s
和 p
,找到 s
中所有 p
的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
示例 1:
输入: s = "cbaebabacd", p = "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
思路:
滑动窗口。
- 界条件检查:在函数开始时,检查
s
的长度是否小于p
的长度,若小于则直接返回空结果。 - 字符计数统计:分别统计字符串
p
中每个字符的出现次数到pmp
中,以及初始窗口内字符的出现次数到smp
中。 - 检查初始窗口:比较
smp
和pmp
,若相等则将起始索引 0 添加到结果中。 - 移动滑动窗口:
i
从plen
开始,每次移动窗口时,移除窗口最左边的字符,添加窗口最右边的字符,并更新smp
。若更新后的smp
和pmp
相等,则将当前窗口的起始索引添加到结果中。
class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> res;int slen=s.size();int plen=p.size();unordered_map<char,int> pmp;for(char x:p){pmp[x]++;}unordered_map<char,int> smp;// 初始化滑动窗口for (int i = 0; i < plen; i++) {smp[s[i]]++;}// 检查初始窗口是否是 p 的字母异位词if (smp == pmp) {res.push_back(0);}for(int i=plen;i<slen;i++){smp[s[i - plen]]--;if (smp[s[i - plen]] == 0) {smp.erase(s[i - plen]);}smp[s[i]]++;if(smp==pmp){res.push_back(i-plen+1);}}return res;}
};
复杂度分析
- 时间复杂度:\(O(n)\),其中 n 是字符串
s
的长度。每个字符最多被访问两次。 - 空间复杂度:\(O(k)\),其中 k 是字符集的大小,主要用于存储
pmp
和smp
。