LeetCode系列76—最小覆盖字串

题意

76. 最小覆盖子串

题解

方法一:滑动窗口

在滑动窗口类型的问题中都会有两个指针,一个用于「延伸」现有窗口的 r 指针,和一个用于「收缩」窗口的 l 指针。在任意时刻,只有一个指针运动,而另一个保持静止。我们在s上滑动窗口,通过移动 r 指针不断扩张窗口。当窗口包含 t 全部所需的字符后,如果能收缩,我们就收缩窗口直到得到最小窗口。

时间复杂度:O(|S|+|T|),这里|S|表示字符串S的长度,|T|表示字符串T的长度

空间复杂度:O(|S|+|T|)

相同类型的题还有LeetCode中的3、209、424、438、567题

class Solution {
    
    
public:
    string minWindow(string s, string t) {
    
    
        int sLen = s.size();
        int tLen = t.size();
        if (sLen == 0 || tLen == 0 || sLen < tLen) {
    
    
            return "";
        }
        int distance = 0, left = 0, right = 0;
        int minLen = sLen + 1, minLeft = 0;
        int winFreq[128];
        int tFreq[128];
        memset(winFreq, 0, 128 * sizeof(int));
        memset(tFreq, 0, 128 * sizeof(int));
        for (const char& c : t) {
    
    
            tFreq[c]++;
        }
        while (right < sLen) {
    
    
            if (tFreq[s[right]] == 0) {
    
    
                right++;
                continue;
            }
            if (winFreq[s[right]] < tFreq[s[right]]) {
    
    
                distance++;
            }
            winFreq[s[right]]++;
            right++;
            while (distance == tLen) {
    
    
                if (right - left + 1 < minLen) {
    
    
                    minLen = right - left + 1;
                    minLeft = left;
                }

                if (tFreq[s[left]] == 0) {
    
    
                    left++;
                    continue;
                }
                if (winFreq[s[left]] == tFreq[s[left]]) {
    
    
                    distance--;
                }
                winFreq[s[left]]--;
                left++;
            }
        }
        return minLen == sLen + 1 ? "" : s.substr(minLeft, minLen);
    }
};

另一种解法

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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Guess you like

Origin blog.csdn.net/younothings/article/details/120069493