题目描述:
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.
寻找在s中能够包含t的所有字符的最小窗口。可以遍历t字符串,记录每个字符出现的次数,为了减少搜索的时间复杂度,采用哈希表(key,count)来进行存储每个字符出现的次数。然后定义两个指针begin和end表示窗口的起始点和终止点,保持begin不变,令end++。每次匹配到t中出现的字符,令hash[s[end]]--,同时定义count变量记录在窗口中已经包含的t中的字符数目,需要注意的是当hash[s[end]]>0时,说明窗口中该字符出现的次数小于t中该字符出现的次数,所以count++,否则count不变。当count=t.size()时,说明窗口中的字符已经包含了t的所有字符。接下来移动begin,从而尽量缩小窗口的长度,当hash.count(s[begin])=0,即s[begin]没有在t中出现,或者hash[s[begin]]<0,即s[begin]在窗口中出现的次数大于t中该字符出现的次数,这两种情况都可以令begin++,因为除去s[begin]后,窗口还是能够保证包含t中的所有字符。以上步骤能够求到以s[end]为结尾的最小窗口,然后令end++,重复上述过程,直到end到达s的末尾,求得对于所有的end中最小的窗口。
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char,int> hash;
for(int i=0;i<t.size();i++)
{
if(hash.count(t[i])==1) hash[t[i]]++;
else hash[t[i]]=1;
}
int begin=0;
int end=0;
int count=0;
string min_window;
while(end<s.size())
{
if(hash.count(s[end])==1&&hash[s[end]]>0)
{
count++;
hash[s[end]]--;
}
else if(hash.count(s[end])==1&&hash[s[end]]<=0) hash[s[end]]--;
if(count==t.size())
{
while(begin<=end)
{
if(hash.count(s[begin])==0) begin++;
else if(hash.count(s[begin])==1&&hash[s[begin]]<0)
{
hash[s[begin]]++;
begin++;
}
else if(hash.count(s[begin])==1&&hash[s[begin]]>=0)
{
if((end-begin)<min_window.size()||min_window.empty())
min_window=s.substr(begin,end-begin+1);
break;
}
}
}
end++;
}
return min_window;
}
};