学习剖析一次: 76. 最小覆盖子串
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""
输入:s = "ADOBECODEBANC", t = "ABC" 输出:"BANC"
class Solution {
public:
unordered_map <char, int> wordCountMap, lrmap;
bool isContainAll() {
for(const auto &p: wordCountMap) {
if(lrmap[p.first] < p.second) {
return false;
}
}
return true;
};
string minWindow(string s, string t) {
for(const auto &c: t) {
++wordCountMap[c];
}
int l = 0, r = -1;
// 俩个字段记录:子串长度和起始位置
int minLen = INT_MAX, minLenLeft = -1
// l...r
while (r < int(s.size()))
{
// 当前字符在Word中,记录总出现次数
// r右指针向前+1
if (wordCountMap.find(s[++r]) != wordCountMap.end())
{
++lrmap[s[r]];
}
// 当lrmap中字符出现次数符合Word
// 判断l-r范围内的字符是否包含所有Word字符
while(isContainAll() && l <= r) {
// 更新最小的长度
if (r - l + 1 < minLen) {
minLen = r - l + 1;
minLenLeft = l;
}
// lrmap所记录s[l]即当前范围内最左端字符次数-1
// l位置右移
if (wordCountMap.find(s[l]) != wordCountMap.end()) {
--lrmap[s[l]];
}
++l;
}
}
return minLenLeft == -1 ? string() : s.substr(minLenLeft, minLen);
};
};