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.
分析:
这道题需要维持一个滑动窗口,可以采用双指针来实现:
对于尾指针,在当前子串不满足要求的时候,需要不断的向后扩展;
对于头指针,在当前子串有冗余的时候,需要向后收缩。
那么,接下来的问题就转化为如何判断当前子串是否包含一个完整的查询字符串。由于不考虑查询字符串的顺序,实际上需要判断的只是当前字符串是否包含查询字符串的分布,可以在程序开始时计算查询串的分布,而在检测时,对当前字符串也计算一个相应的分布。当前字符串中各个查询字符的计数可能会大于所需的计数,这时就会产生冗余,因此需要一个变量来统计当前有效的字符数目。当有效字符的数目等于(不可能大于)查询字符串长度时,就满足了收缩头指针的条件。
class Solution {
public:
string minWindow(string s, string t) {
const int len = 256;
int s_cnt[len],t_cnt[len];
memset(s_cnt,0,sizeof(s_cnt));
memset(t_cnt,0,sizeof(t_cnt));
for(int i=0;i<t.size();++i) t_cnt[t[i]]++;
int beg = 0,wbeg = 0,wlen = INT_MAX,real=0;
for(int i=0;i<s.size();++i)
{
if(t_cnt[s[i]]>0)
{
s_cnt[s[i]]++;
if(s_cnt[s[i]]<=t_cnt[s[i]]) real++;
}
if(real==t.size())
{
while(s_cnt[s[beg]]>t_cnt[s[beg]]||t_cnt[s[beg]]==0)
{
s_cnt[s[beg]]--;
beg++;
}
if(wlen>i-beg+1)
{
wbeg = beg;
wlen = i-beg+1;
}
}
}
if(wlen==INT_MAX) return "";
return s.substr(wbeg,wlen);
}
};