题目:
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).
Example:
Input: S = "ADOBECODEBANC", T = "ABC" Output: "BANC"
Note:
- If there is no such window in S that covers all characters in T, return the empty string
""
. - If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
描述:
给出一个主串s和一个目标串t,求s中包含t中所有字符的最短子串,要求线性时间复杂度...
分析:
第一想法是尺取法,不过具体的实现在经典的尺取法上有一些改动,
具体算法如下:
1,找到从起始位置开始且满足题意的最短串,标记起点和终点,
2,尝试将起点位置右移,直到两个端点间的字符串不符合要求,
3,将终点后移,直到端点间的串满足题意,
4,遍历到最后一个位置处,算法结束。
在整个算法中,记录满足题意的最短串的起始位置,最后截取即可..
(最近比较忙,这个题搁置了好几天才搞定...)
数据:
"a"
"b"
"a"
"aa"
"AbcAbcc"
"bcc"
"ADOBECODEBANCABC"
"ABC"
"BEBACABC"
"ABC"
"BECBA"
"ABC"
"AAAAA"
"AA"
代码:(时间复杂度 O(n),虽然看起来有三层循环;空间复杂度O(1),只用到了两个256元素的数组(起始应该可以开的更小点))
class Solution {
public:
string minWindow(string s, string t) {
int len = s.size(), begin = 0, end = -1;
int cnt = t.size();
int count[256] = { 0 };
for (int i = 0; i < t.size(); ++i) {
++ count[t[i]];
}
int start = 0;
int visit[256] = { 0 };
for (int i = 0; i < len; ++ i) {
++ visit[s[i]];
if (visit[s[i]] > count[s[i]]) {
continue;
}
-- cnt;
while (!cnt) {
if (end == -1 || i - start < end - begin) {//找到更短的了
begin = start;
end = i;
}
-- visit[s[start]];
if (visit[s[start]] < count[s[start]]) {
++ cnt;
}
++start;
}
}
return s.substr(begin, end - begin + 1);
}
};