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.
在细节处理上还是显得不够熟练,半天才写出代码,感觉自己很挫啊。而且又一次没有完全理解题意,一开始以为只要找字母集,没考虑字母数量,不过还好两者只在判断条件上有点差别,很快改好了。
这个题很直观的是O(n ^ 3)两重循环解枚举上下界再一重循环检查,但它要求线性复杂度,考虑一下,发现设x到是符合条件的一段,x + 1要找符合条件的一段,只要向前再找到一个x位置上的字母即可,思想很简单,接下来苦逼的是代码。
class Solution {
bool own(int c[], int s[])//检查函数
{
for(int i = 0; i < 260; i++)
{
if(s[i] > c[i])
{
return false;
}
}
return true;
}
public:
string minWindow(string S, string T) {
if(S.length() == 0 || S.length() < T.length())
{
return "";
}
const int len = S.length();
int c[260], sign[260];
for(int i = 0; i < 260; i++)
{
c[i] = sign[i] = 0;
}
for(int i = 0, len = T.length(); i < len; i++)
{
int a = T[i];
sign[a]++;
}
int start = len, end = len;
while(start > 0 && !own(c, sign))//先找到从尾巴开始的第一段
{
--start;
c[S[start]]++;
}
if(!own(c, sign))//如果S包含不了T
{
return "";
}
int minStart = start, minEnd = end;
for(end = len - 1; end > 0; end--)
{
int idx = S[end];
c[idx]--;
if(sign[idx] > c[idx])//缺自母了
{
while(--start > 0 && S[start] != idx)//缺失的字母还在前面
{
c[S[start]]++;
}
if(S[start] != idx)//缺失的那个字母没了
{
break;
}
c[idx]++;
}
if(end - start < minEnd - minStart)
{
minStart = start;
minEnd = end;
}
}
return S.substr(minStart, minEnd - minStart);
}
};