Leetcode笔记目录
一、题目描述
给你一个字符串 S、一个字符串 T 。请你设计一种算法,可以在 O(n) 的时间复杂度内,从字符串 S 里面找出:包含 T 所有字符的最小子串.
示例1:
- 输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
二、解题过程
1.思想
双指针的滑动窗口问题,其过程为右端点移动得到一个满足条件区间,然后左端点移动得到第一个不满足条件区间,然后右端点再移动,这样循环直到遍历一遍:
- 首先用hash数组得到T中每个字符的数量,用它来判断是否满足题设条件;
- 右端点移动到第一个包含T中所有字符的位置,左端点移动到S中第一个含有T中字符的位置;
- 右端点再次向右移动到第一个包含T中所有字符的位置,即移动到上一次左端点移动到的那个字符,然后左端点再次向右移动到S中第一个含有T中字符的位置,且要求该字符右端点移动时没有扫到(扫到说明此时双指针区间已经有该字符了),这样循环并记录比较每次的区间大小,直到遍历一遍数组。
2.代码
string minWindow(string s, string t) {
vector<int> hash(128,0);
vector<bool> isexist(128,false);
int cnt=0;
for(int i=0;i<t.size();i++){
hash[t[i]]++; //错误1
isexist[t[i]]=true;
}
int min=s.size()+1,mini=0,i=0;
for(int j=0;j<s.size();j++){
if(isexist[s[j]]){
if(--hash[s[j]]>=0) //错误2
cnt++;
}
while(cnt==t.size()){
if(j-i+1<min){
min=j-i+1;
mini=i;
}
if(isexist[s[i]]&&++hash[s[i]]>0){cnt--;}
i++;
}
}
return min>s.size()?"":s.substr(mini,min); //错误3
}
- 错误
- 128是ASCII码的数量;
- 注意循环的结构,以及怎样实现双指针维持一个满足条件的区间;
- 使用字符串的substr方法;
三、总结
尽管知道是滑动窗口,但实现的许多细节需要特别注意。