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.
思路:这道题比较难, 开始花了比较大的力气只完成了T中没有重复字符的最小窗口(用查找)。后来参考了 https://github.com/soulmachine/leetcode 这里的代码,我已经看到几次在字符串查找中使用开256大小的int数组的方法了,主要是当找到完全包含T的一个窗口后(这个过程有点tricky), 动态维护一个最小窗口. 动态维护的过程比较巧妙, 逻辑上要严谨.
参考代码:
class Solution {
public:
string minWindow(string S, string T) {
if(S.empty() || T.empty() || S.length() < T.length())
return "";
const int CHAR_SIZE = 256;
int appeared[CHAR_SIZE], expected[CHAR_SIZE], start = 0, matched = 0, min_start = 0, minlen = INT_MAX;
memset(appeared, 0, sizeof(appeared));
memset(expected, 0, sizeof(appeared));
for(int i = 0; i<T.length(); ++i)
++expected[T[i]];
for(int i = 0; i<S.length(); ++i)
{
if(expected[S[i]])
{
if(appeared[S[i]]<expected[S[i]])
{
++matched;
}
++appeared[S[i]];
if(matched == T.length())
{
while(!expected[S[start]] || appeared[S[start]] > expected[S[start]])
{
if(appeared[S[start]] > expected[S[start]])
{
--appeared[S[start]];
}
++start;
}
if(minlen > i-start+1)
{
min_start = start;
minlen = i - start + 1;
}
}
}
}
if(matched<T.length())
return "";
return S.substr(min_start, minlen);
}
};
class Solution {
public:
string minWindow(string S, string T) {
string ans;
if(S.empty() || S.length()<T.length())
return ans;
vector<int>bucket(256, 0), already(256, 0);
int tlen = T.length(), head = 0, tail = 0, cnt = 0;
for(int i = 0; i<tlen; ++i)
++bucket[T[i]];
while(tail<S.length()) {
if(already[S[tail]] < bucket[S[tail]]) {
++already[S[tail]];
++cnt;
} else if(bucket[S[tail]]) {
++already[S[tail]];
} else {
++tail;
continue;
}
++tail;
if(cnt == tlen) {
while(head<tail && (!bucket[S[head]] || already[S[head]]>bucket[S[head]])) {
if(!bucket[S[head]]){
++head;
continue;
}
--already[S[head++]];
}
if(head<tail && (ans.empty() || tail-head<ans.length()))
ans = S.substr(head, tail-head);
}
}
return ans;
}
};