无重复字符最长子串
解题思路:
滑动窗口即为,通过左右指针来控制一块区域的左右边界,通过判断条件来扩展右边界或收缩左边界
本题是标准的滑动窗口,题目要求我们找到无重复最长的子串,这里就可以知道移动窗口的条件了
1、当前的值在当前窗口中并没有重复的字符,便继续扩展右边界
2、当前值在当前窗口中发现有重复的字符,就需要收缩左边界,并且直到条件不满足
下面是代码:
cpp
int lengthOfLongestSubstring(string s){
unordered_set<int> se;
int left = 0;
int res = 0;
for(int right = 0;right<s.size();right++){
while(se.find(s[right])!=se.end()){
se.erase(s[left]);
left++;
}
se.insert(s[right]);
res = max(res, right-left+1);
}
return res;
}
找到字符串中所有字母的异位词
438. 找到字符串中所有字母异位词 - 力扣(LeetCode)


解题思路:
本题的主要思路就是通过滑动窗口来统计当前区间字符,然后通过判断是否与匹配串是否属于异位词,然后收集结果
那应该怎么去判断是否是异位词,我们可以通过hash表去完成比较,如果当前区间中的字符收集后与匹配串完全相同,就说明碰到了异位词,然后计算起始位置进行结果的收集。
但需要注意的是当当前的区间长度比匹配串还要短说明一定不符合要求就没有必要继续做下面的步骤了,可以直接continue,继续扩张右边界
还有最后需要收缩左边界的时候,不能直接对left所处位置的字符erase,因为这会导致如果删除当前区间中非left位置但是与left位置的字符相同的次数统计,我们只有当left位置的值为0了,才对其进行erase,避免前面判断错误
cpp
vector<int> findAnagrams(string s, string p){
unordered_map<char, int> pp;//统计匹配串p的字符出现次数
unordered_map<char, int> ss;//模式串的字符出现次数
for(char str : p){//统计匹配串p的字符出现次数
pp[str]++;
}
int left = 0;
vector<int> res;
for(int right = 0;right<s.size();right++){
ss[s[right]]++;//记录右端点
int pos = right-p.size()+1;//记录起始位置
if(pos<0) continue;//剪枝
//此时模式串和匹配串到目前为止发现了异位词进行收集结果
if(pp==ss){
res.push_back(pos);
}
ss[s[left]]--;//收缩左区间
if(ss[s[left]]==0){
ss.erase(s[left]);
}
left++;
}
return res;
}