题目原文:
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”
题目大意:
给出一个字符串S和字符串T,在S中寻找一个长度最短的子串,使其包含T中所有的字符,要求在O(n)内完成。
题目分析:
首先使用HashMap记录T串中每个字母出现的次数(也可以简化为char数组). 在S中用[l,r]代表滑动窗口。S中,每次循环r右移1位,然后判断r右移之后所指向的字符是否在Hash表中出现过:如果出现过,则表示在T中。此时通过计数器cnt判断T中字符是否都出现过,如果是,则记录l和r之间子串长度,并与最短长度比较。然后逐步右移l并在Hash表中删除l指向的字符直到计数器cnt小于T中字符数量。
注意一下,由于T中同一字符的数量可能减到负值,因此需要2重判断:先判断是否出现此字符,在判断此字符出现的具体数量。
源码:(language:cpp)
class Solution
{
public:
string minWindow(string S, string T)
{
int c[128] = {0};
bool flag[128] = {false};
for(int i = 0; i < T.size(); ++ i)
{
flag[T[i]] = true;
++ c[T[i]];
}
int cnt = 0, l = 0, minl = 0, minsize = S.size() + 1;
for(int r = 0; r < S.size(); ++ r)
if(flag[S[r]])
{
if(-- c[S[r]] >= 0)
++ cnt;
while(cnt == T.size())
{
if(r - l + 1 < minsize)
minl = l, minsize = r - l + 1;
if(flag[S[l]])
if(++ c[S[l]] > 0)
-- cnt;
++ l;
}
}
if(minsize > S.size())
return "";
return S.substr(minl, minsize);
}
};
成绩:
16ms,53.63%,12ms,23.77%