题目:
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC"
.
Note:
If there is no such window in S that covers all characters in T, return the emtpy string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
解法:首先建立两个表needtofind和hastofind;再建立头尾两个位置指针begin 和 end;详细解释看代码,很清晰。
#include<iostream>
#include<string>
#include <map>
using namespace std;
string minWindow(string S, string T) {
string res;
int lenT = T.size();
int lenS = S.size();
if(lenS < lenT || lenS == 0)//如果S的长度小于T的长度,那么就不用找了。
return res;
map<char, int>needtofind,hastofind;
for(int i = 0; i < lenT; ++i){
needtofind[T[i]]++;
}
int begin, end;//定义两个位置指针;
int k = lenT;
begin = end = 0;
for(int i = 0; i < lenS; ++i){
if(T.find(S[i]) == string::npos)//如果不是要找的字母那就跳过找下一个
continue;
else {
hastofind[S[i]]++;
if(k == lenT)//如果是第一个找到的字母,那就记录位置
begin = i;
if(hastofind[S[i]] <= needtofind[S[i]])//当找到的个数小于需要找到的个数时,说明第一个子串还没有找完,
k--;
if(k == 0 && hastofind[S[i]] == needtofind[S[i]]){//k == 0;说明第一个子串找到,后面那个主要是保证接下来找的时候,要保证子串的完整;
end = i;
res = S.substr(begin,end - begin + 1);
}
if(k <= 0){//在找到的子串中寻找更小的子串,比如bba,要找ab,那么就是在子串中寻找。
end = i;
int j = begin;
for(; j < i; ++j){
if(T.find(S[j]) == string::npos)
continue;
if(hastofind[S[j]] > needtofind[S[j]]){//向后移动一个,就要把已经找到的减去一个
hastofind[S[j]]--;
continue;
}
if(hastofind[S[j]] == needtofind[S[j]]){
if(j == begin)//如果等于begin,那说明向后移动的哪一个不是和第一个相同的,所以就要跳出。
break;
begin = j;
string tmp = S.substr(begin,end - begin + 1);
if(tmp.size() < res.size())
res = tmp;
break;
}
else
break;
}
}
}
}
return res;
}
int main()
{
string S("cabwefgewcwaefgcf");
string T("cae");
string res = minWindow(S,T);
cout<<res<<endl;
cin.get();
return 0;
}