int had = 0; int b = 0, e = 0; string tmpt = t; map<char, int> used; for (int i = 0; i < s.size(); ++i) { int indx = tmpt.find(s[i]); if (indx == string::npos) { ++used[s[i]]; continue; } tmpt.erase(tmpt.begin() + indx);
if (had++ == 0) b = i; if (tmpt.size() == 0) { e = i; break; } } if (had != t.size()) return {};
int rb = b, re = e; while (b < s.size()) { char need = s[b++]; while (b < s.size() && t.find(s[b]) == string::npos) b++; if (b >= s.size()) break;
if (used[need] > 0) { if (e - b < re - rb) { rb = b; re = e; } --used[need]; continue; }
while (++e < s.size() && s[e] != need) ++used[s[e]];
if (e >= s.size()) break; elseif (e - b < re - rb) { rb = b; re = e; } }
return s.substr(rb, re - rb + 1); } };
代码量挺大的…
简单来说, 我的想法是首先找到最左边包含所有字符的最小子串, 然后 slide window , 慢慢移动到字符 S 尾端