模板来源见:https://www.bilibili.com/video/BV1V44y1s7zJ?spm_id_from=444.41.header_right.fav_list.click
具体模板如下:
解释:
①这里的result相当于判断条件,比如不相同的元素个数=2;窗口中的元素个数=某字符串长度。
②bestResult指需要返回的结果,通常是长度,如果要返回字符串的话另外设置两个变量begin和end记录符合条件的数组下标,不然在窗口移动的时候left和right会变得面目全非。
③最长/最短模板的区别和联系在于:当result满足条件时一定要及时更新返回值。
代入做题:
159至多包含两个不同字符的最长子串:
class Solution {
public:
int lengthOfLongestSubstringTwoDistinct(string s) {
unordered_map<char,int> ooc;
int left=0,right=0,ans=0;
int cnt=0;
while(right<s.size()){
if(ooc[s[right]]==0) cnt++;
ooc[s[right]]++;
while(cnt>2){
ooc[s[left]]--;
if(ooc[s[left]]==0) cnt--;
left++;
}
ans=max(ans,right-left+1);
right++;
}
return ans;
}
};
3.无重复字符的最长子串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char,int>ooc;
int left=0,right=0,len=0;
while(right<s.size())
{
ooc[s[right]]++;
while(ooc[s[right]]>=2)//为什么用s[right]判断,是因为前面的元素肯定至多出现一次
{
ooc[s[left]]--;
left++;
}
len=max(len,right-left+1);
right++;
}
return len;
}
};
209.长度最小的子数组
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left=0,right=0,current=0,len=INT_MAX;
while(right<nums.size()){
current+=nums[right];
while(current>=target){
len=min(len,right-left+1);
current-=nums[left];
left++;
}
right++;
}
if(len==INT_MAX) return 0;
return len;
}
};
76.最小覆盖子串
class Solution {
public:
string minWindow(string s, string t) {
int begin=0,end=0;
int left=0,right=0,numfound=0;
int minlen=INT_MAX;
unordered_map<char,int> hashs; //hashs记录s中滑动窗口对应的hash表
unordered_map<char,int> hasht;//hasht记录t中字符出现的数量,注意可以重复,例如t=ABCC
for(int i=0;i<t.size();i++)
hasht[t[i]]++;
string ans;
while(right<s.size()){
hashs[s[right]]++;
if(hashs[s[right]]<=hasht[s[right]])//说明找到了正好需要的元素
numfound++;
while(numfound==t.size()){
if(right-left+1<minlen){
minlen=right-left+1;
begin=left;
end=right;
}//接下,而在此条件中滑动窗口中的t中字符数量必然>=t中字符数量,因为已经满足numfound=t.size()了,所以直接用==判断
if(hashs[s[left]]==hasht[s[left]]) //举个例子 s=AOCCCDEBACFGB t=ABCC 那左指针扫到CCC中第一个C时其实numfound不用--的
numfound--;
hashs[s[left]]--;
left++;
}
right++;
}
if(minlen==INT_MAX) return "";
return s.substr(begin,minlen);
}
};