给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC" 输出: "BANC"
说明:
- 如果 S 中不存这样的子串,则返回空字符串
""
。 - 如果 S 中存在这样的子串,我们保证它是唯一的答案。
1 //使用滑动窗口 2 //我们最开始先扫描一遍T,把对应的字符及其出现的次数存到 HashMap 中。 3 // 4 //- 然后开始遍历S,就把遍历到的字母对应的 HashMap 中的 value 减一,如果减1后仍大于等于0,cnt 自增1。 5 // 6 //- 如果 cnt 等于T串长度时,开始循环,纪录一个字串并更新最小字串值。然后将子窗口的左边界向右移,如果某个移除掉的字母是T串中不可缺少的字母,那么 cnt 自减1,表示此时T串并没有完全匹配。 7 // 8 //解法一: 9 10 class Solution { 11 public: 12 string minWindow(string s, string t) { 13 string res = ""; 14 unordered_map<char, int> letterCnt; 15 int left = 0, cnt = 0, minLen = INT_MAX; 16 for (char c : t) ++letterCnt[c];//记录子串中的相同字母个数 17 for (int i = 0; i < s.size(); ++i) { 18 if (--letterCnt[s[i]] >= 0) ++cnt; 19 while (cnt == t.size()) { 20 if (minLen > i - left + 1) { 21 minLen = i - left + 1; 22 res = s.substr(left, minLen); 23 } 24 if (++letterCnt[s[left]] > 0) --cnt;//还有重复的字母 25 ++left; 26 } 27 } 28 return res; 29 } 30 }; 31 32 33 34 //这道题也可以不用 HashMap,直接用个 int 的数组来代替,因为 ASCII 只有256个字符, 35 //所以用个大小为256的int数组即可代替 HashMap,但由于一般输入字母串的字符只有128个, 36 //所以也可以只用128,其余部分的思路完全相同,虽然只改了一个数据结构,但是运行速度提高了一倍, 37 //说明数组还是比 HashMap 快啊,代码如下: 38 39 40 class Solution { 41 public: 42 string minWindow(string s, string t) { 43 string res = ""; 44 vector<int> letterCnt(128, 0); 45 int left = 0, cnt = 0, minLen = INT_MAX; 46 for (char c : t) ++letterCnt[c]; 47 for (int i = 0; i < s.size(); ++i) { 48 if (--letterCnt[s[i]] >= 0) ++cnt; 49 while (cnt == t.size()) { 50 if (minLen > i - left + 1) { 51 minLen = i - left + 1; 52 res = s.substr(left, minLen); 53 } 54 if (++letterCnt[s[left]] > 0) --cnt; 55 ++left; 56 } 57 } 58 return res; 59 } 60 };