题目:
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.
思路:
最基本的思路是设置一个首指针与一个尾指针,当未包含所有字符时,尾指针移动;当包含重复字符时,首指针移动。每次恰好包含所以字符时,记录是否为最小长度。这个方法的问题是尾指针经过的无效点,首指针可能会重复经过。如下例,首指针不动时,尾指针移动直到包含a…b,当尾指针移动到a…b…a时首指针开始移动,这时首指针需要重复移动尾指针经过的位置。 artwekbreqlawerla
优化的思路是针对每一个字符建立一个队列来记录字符出现的位置,当队列中的字符数大于T中需要的字符数时,队列中的首个字符便可以出列。 备注:ASCII码中有效的字符从’!’开始,共95个。
代码:
class Solution {
public:
string minWindow(string S, string T) {
int letters[95];
int total = 0;
for(int i=0;i<95;i++)
{
letters[i] = 0;
}
for(int i=0;i<T.size();i++)
{
total++;
letters[char2Int(T[i])] += 1;
}
int hasLetter[95];
for(int i=0;i<95;i++)
{
hasLetter[i]=0;
}
queue<int>* letterqueue = new queue<int>[95];
int count=0;
int min_s = 0;
int min_e = S.size();
for(int i=0;i<S.size();i++)
{
if(letters[char2Int(S[i])]>0)
{
if(hasLetter[char2Int(S[i])]<letters[char2Int(S[i])])
{
count++;
}
else if(hasLetter[char2Int(S[i])]!=0)
{
letterqueue[char2Int(S[i])].pop();
hasLetter[char2Int(S[i])]-=1;
}
hasLetter[char2Int(S[i])]+=1;
letterqueue[char2Int(S[i])].push(i);
if(count==total)
{
int s=S.size();
int e = 0;
for(int j=0;j<95;j++)
{
if(letterqueue[j].size()>0)
{
if(s>letterqueue[j].front())
{
s=letterqueue[j].front();
}
if(e<letterqueue[j].back())
{
e=letterqueue[j].back();
}
}
}
if(e>=s&&min_e-min_s>e-s)
{
min_s = s;
min_e = e;
}
}
}
}
if(min_e!=S.size())
{
return S.substr(min_s,min_e-min_s+1);
}
else
{
return "";
}
}
int char2Int(char c)
{
return c-'!';
}
};