var minWindow = function (s, t) { let need = {};//需要覆盖的字符串频数 let window = {};//滑动窗口的字符串频数 for (let a of t) { need[a] = (need[a] || 0) + 1;//统计t中字符频数 } //左右指针 let left = 0, right = 0; let valid = 0;//滑动窗口中能覆盖的字符种类数 let start = 0,//最小覆盖子串的起始索 len = Number.MAX_VALUE;//最小覆盖子串长度 while (right < s.length) { let c = s[right];//进入滑动窗口右边的字符 right++;//右移窗口 if (need[c]) {//如果当前字符在need字符中 更新window中字符数 window[c] = (window[c] || 0) + 1; if (window[c] == need[c]) {//如果当前窗口和需要的字符数量一致时,字符种类+1 valid++; } } while (valid == Object.keys(need).length) {//字符种类与需要的字符个数一致时,就收缩窗口 if (right - left < len) {//当前窗口长度小于之前窗口的长度len 更新最小覆盖子串的起始位置和长度 start = left; len = right - left; } let d = s[left];//需要被移除的字符 left++;//左移窗口 从窗口中移除字符 if (need[d]) {//如果在需要的字符中 更新window中字符数 if (window[d] == need[d]) {//如果当前窗口和需要的字符数量一致时,字符种类-1 valid--; } window[d]--; } } } //没有找到覆盖子串 返回'' 否则返回覆盖子串 return len == Number.MAX_VALUE ? "" : s.substr(start, len);};
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)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。