给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = “ADOBECODEBANC”, t = “ABC”
输出:”BANC”
示例 2:
输入:s = “a”, t = “a”
输出:”a”
示例 3:
输入: s = “a”, t = “aa”
输出: “”
解释: t 中两个字符 ‘a’ 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。
双指针方案
核心问题是判断窗口内的子串是否覆盖了目标串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| class Solution { unordered_map<char, int> mapT, mapS; public: string minWindow(string s, string t) { int sLen = s.size(); int tLen = t.size(); if (sLen == 0 || tLen == 0 || sLen < tLen) { return ""; }
for (auto c : t) { ++mapT[c]; } int begin=0,count=sLen+1; int left = 0, right = 0; int distance = 0; while (right < sLen) { if (mapT[s[right]] == 0) { right++; continue; } if (mapS[s[right]] < mapT[s[right]]) { distance++; } ++mapS[s[right]]; right++;
while (distance == tLen) { if (right-left < count) { begin = left; count = right-left; }
if (mapT[s[left]] == 0) { left++; continue; } if (mapS[s[left]] == mapT[s[left]]) { distance--; } --mapS[s[left]]; left++; }
}
if (count == sLen+1) { return ""; } return s.substr(begin, count); } };
|