需要理解涵盖这样操作如何判别,还是一样用两个数组,一个数组存t串的所有字符,另一个数组用来双指针遍历s判断涵盖否。遍历的过程中更新最小的涵盖长度。
class Solution {
bool is_covered(int cnt_s[],int cnt_t[])
{
for(int i='a';i<='z';i++)
{
if(cnt_s[i]<cnt_t[i])
{
return false;
}
}
for(int i='A';i<='Z';i++)
{
if(cnt_s[i]<cnt_t[i])
{
return false;
}
}
return true;
}
public:
string minWindow(string s, string t) {
//主要理解涵盖的意思
int m=s.length();
int ans_left=-1,ans_right=m;//记录子串的左边和右边,这样初始化就为了s==t的情况,这样还是会更新ans
int cnt_s[128]{};
int cnt_t[128]{};
for(char c:t)//将t串存储
{
cnt_t[c]++;
}
int left=0;//左指针,子串起点
for(int right=0;right<m;right++)
{
cnt_s[s[right]]++;//将s串的右指针所指向加入数组
while(is_covered(cnt_s,cnt_t))//判断是否涵盖
{
if(right-left<ans_right-ans_left)//如果涵盖了那么长度就是right-left,更新ans的长度
{
ans_left=left;
ans_right=right;
}
cnt_s[s[left++]]--;//涵盖了说明应该将左指针继续右移找后续有无涵盖
}
}
return ans_left<0?"":s.substr(ans_left,ans_right-ans_left+1);
}
};