class Solution {
public:
unordered_map <char, int> ori, cnt;
bool check() {
for (const auto &p: ori) {
if (cnt[p.first] < p.second) {
return false;
}
}
return true;
}
string minWindow(string s, string t) {
for (const auto &c: t) {
++ori[c];
}
int l = 0, r = -1;
int len = INT_MAX, ansL = -1, ansR = -1;
while (r < int(s.size())) {
if (ori.find(s[++r]) != ori.end()) {
++cnt[s[r]];
}
while (check() && l <= r) {
if (r - l + 1 < len) {
len = r - l + 1;
ansL = l;
}
if (ori.find(s[l]) != ori.end()) {
--cnt[s[l]];
}
++l;
}
}
return ansL == -1 ? string() : s.substr(ansL, len);
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/minimum-window-substring/solution/zui-xiao-fu-gai-zi-chuan-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
string minWindow(string s, string t) {
vector<int> chars(128,0);
//标准ASCII码字符集总共的编码有128个
vector<bool> flag(128,false);
for(auto& ch : t){
++chars[ch];
flag[ch] = true;
}
//记录是否出现和出现的次数
//l是用于移动的边界,min_l是为了取得子串的边界。
int cnt = 0,l = 0,min_l = 0,min_size = s.size() + 1;
for(int r = 0;r < s.size();r++){
if(flag[s[r]]){
//cnt++;不能够直接计数,这样会造成可能重复出现某个数字,但是其他的没有出现过
if(--chars[s[r]] >= 0){
cnt++;
}//感觉这个和信号量好像
//如果 < 0,弄多了
while(cnt == t.size()){
//只有比原先小的时候才更新
if(r - l + 1 < min_size){
min_size = r - l + 1;
min_l = l;
}
//尝试缩减左边界
if(flag[s[l]] && ++chars[s[l]] > 0){
cnt--;
}
l++;
}
}
}
//要考虑到找不到子串只能返回空串的情况。
return min_size > s.size() ? "":s.substr(min_l,min_size);
}
};