题目描述
给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:
- 如果 S 中不存这样的子串,则返回空字符串
""
。 - 如果 S 中存在这样的子串,我们保证它是唯一的答案。
解题思路
采用滑动窗口,窗口有左右边界,先通过扩展右边界找出一个包含T中所有字符的子串,然后收缩左边界,直到不能再收缩。记录此时的子串。然后收缩左边界,继续扩展右边界,直到再找到满足要求的子串,和上次的进行比较,保存更小的子串。返回执行,直到右边界到达S串尾,且左边界不能再收缩。
代码
1 class Solution { 2 public: 3 string minWindow(string s, string t) { 4 int slen = s.length(), tlen = t.length(), left = 0, right = 0, minLen = INT_MAX, cnt = 0; 5 string res = ""; 6 if(slen < tlen || tlen == 0 || slen == 0) return ""; 7 map<char, int> m; 8 for(int i = 0; i < t.size(); i++){ 9 if(m.find(t[i]) == m.end()) 10 m[t[i]] = 0; 11 m[t[i]]++; 12 } 13 while(right < slen){ 14 if(m.find(s[right]) != m.end()){ 15 m[s[right]]--; 16 if(m[s[right]] >= 0) cnt++; 17 while(cnt == tlen){ 18 if(right - left + 1 < minLen){ 19 minLen = right - left + 1; 20 res = s.substr(left, minLen); 21 } 22 if(m.find(s[left]) != m.end()){ 23 if(m[s[left]] >= 0) cnt--; 24 m[s[left]]++; 25 } 26 left++; 27 } 28 } 29 right++; 30 } 31 return res; 32 } 33 };