题目:https://leetcode.com/problems/minimum-window-substring/#/description
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 empty string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
用双指针+map来做,我用的方法比较直观易懂。map<char, int> charactor记录t中个元素的个数,然后遍历s,遇到t中的值,就让charactor里-1,当charactor全为0时,就是一个满足条件的值。用start作左指针,当剔除start所在元素,还满足条件,且长度较小,就更新答案。
我的代码
string minWindow(string s, string t)
{
map<char, int> charactor;
int left=0, right=-1;
int start=0;
int num;//numbers of contained charactors
int len=INT_MAX;
for(int i=0; i<t.length(); ++i)
++charactor[t[i]];
num = charactor.size();
for(int i=0; i<s.length(); ++i)
{
if(charactor.find(s[i]) != charactor.end())
{
--charactor[s[i]];
if(charactor[s[i]] == 0)
--num;
if(charactor[s[i]]<=0 && num==0)
{
while(start<=i)
{
if(charactor.find(s[start])!=charactor.end() && charactor[s[start]]>=0)
{
if(i-start+1 < len)
{
left = start;
right = i;
len = i-start+1;
}
break;
}
if(charactor.find(s[start])!=charactor.end() && charactor[s[start]]<0)
++charactor[s[start]];
++start;
}
}
}
}
return s.substr(left, right-left+1);
}
solution top1
solution里的第一个答案,有很多改进的地方,不再记录num,只用记录一个counter = t.length(),当counter=0时,就是合法值。 不需用一个真的map,可以用vector<int> map(128,0)来代替, 初始值为t中各元素的个数,移动end,所到之处-1,begin所到之处+1,这样就不需要判断begin所在的元素是不是t中,因为他们的map值永远<=0, 而在t中的元素的map值用于>=0
top1的代码
string minWindow(string s, string t) {
vector<int> map(128,0);
for(auto c: t) map[c]++;
int counter=t.size(), begin=0, end=0, d=INT_MAX, head=0;
while(end<s.size()){
if(map[s[end++]]-->0) counter--; //in t
while(counter==0){ //valid
if(end-begin<d) d=end-(head=begin);
if(map[s[begin++]]++==0) counter++; //make it invalid
}
}
return d==INT_MAX? "":s.substr(head, d);
}