问题描述
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.
问题分析
这是一道处理字符串子串的问题,可以用滑动窗口来解决。对于string s 和string t, 我们要在s中找到包含t中的字符的最小字串。窗口包含left,right两个指针,因此我们需要遍历s中的每个字符,再看他是否在string t中,这里查看字符是否在t串中的步骤很关键,我们可以使用map来解决,统计t中各个字符出现的次数。如果遍历中的字符在t串中,对应的map的映射值-1,如果-1后还大于0则说明改字符在t串中,并使用一个计数器cnt++,来计算窗口已经包含的t中的字符。如果cnt == t.size(),则说明窗口完全包含t中的字符。更新窗口大小。此时为了寻找更小的窗口,我们将left指针右移,来缩小窗口。具体操作为left所指的字符的映射值++,如果大于0,说明该字符在t中,cnt–. ;如果等于0则说明left所指的字符不在t中。
代码
class Solution {
public:
string minWindow(string s, string t) {
string res ="";
int minLen = INT_MAX;
if(s.size() == 0 ||t.size() ==0 ) return "";
map<char, int> m;
for(int i = 0; i<t.size();i++)//统计字符个数
{
++m[t[i]];
}
int left = 0,right = 0;
int cnt =0;
for(right =0; right<s.size();right++)//遍历s
{
if(--m[s[right]]>=0)//T中有s[right]
{
cnt++;
}
while(cnt == t.size())//如果字串的字符全在里面
{
if(minLen>right-left+1){
minLen = right-left+1;
res = s.substr(left,minLen);
}
if(++m[s[left]]>0) cnt--;
left++;
}
}
return res;
}
};