题目链接:最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

方法:滑动窗口

class Solution {
public:
    string minWindow(string s, string t) {
        if (s.empty() || t.empty() || t.size() > s.size()) {
            return "";
        }

        int need[128] = {0};
        for (char c : t) {
            need[(unsigned char)c]++;
        }

        int needCount = t.size();     // 还需要匹配多少字符
        int left = 0, right = 0;
        int minLen = INT_MAX;         // 当前找到的最短长度
        int start = 0;                // 最优区间的起始位置

        while (right < (int)s.size()) {
            char rc = s[right];
            if (need[(unsigned char)rc] > 0) {
                needCount--;          // 用掉一个需要的字符
            }
            need[(unsigned char)rc]--; // 窗口中多了一个 rc
            right++;

            // 当前窗口已经包含了所有需要的字符,开始尽量缩小左边界
            while (needCount == 0) {
                // 更新最小区间
                if (right - left < minLen) {
                    minLen = right - left;
                    start = left;
                }

                char lc = s[left];
                need[(unsigned char)lc]++; // 移出左边字符
                if (need[(unsigned char)lc] > 0) {
                    // 移出了一个“必须”的字符,窗口不再满足条件
                    needCount++;
                }
                left++;
            }
        }

        // 注意 substr 的第二个参数是长度,不是右边界
        return minLen == INT_MAX ? "" : s.substr(start, minLen);
    }
};

标签: hot100, Hard, 滑动窗口

添加新评论