LeetCode刷题笔记——最小覆盖子串

LeetCode刷题笔记——最小覆盖子串

题目描述

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

思路

本问题要求返回字符串s中包含字符串t的全部字符的最小窗口。我们将包含t的全部字母的窗口称为可行窗口。滑动窗口思想上,有两个指针,一个是用来收缩窗口的l指针,另外一个是用来扩展窗口的r指针。在任意时刻,都只有一个指针在运动,另外一个保持静止。
我们在s上滑动窗口,通过 移动r指针不断扩张窗口 。当窗口包含t全部所需的字符后,如果能收缩,就将窗口收缩直到得到最小窗口, 通过l指针进行收缩。收缩到不满足check条件为止

主要操作:先进行扩展操作,当扩展到满足check条件后,试图收缩,收缩到不满足check,继续扩展。。。。。。。。

问题:如何判断窗口中包含的t中所需的字符数?用哈希表来保存字符和个数。

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);
    }
};

labuladong解法:

class Solution {
public:
    string minWindow(string s, string t) {
        unordered_map<char,int> window,need;
        for(char item : t)
            need[item]++;
        int l=0,r=0;
        int valid=0;
        int start=0,len=INT_MAX;
        while(r<s.size()){
            char c=s[r++];
            if(need.count(c)){
                window[c]++;
                if(window[c]==need[c])
                    valid++;
            }
            while(valid==need.size()){
                if(r-l<len){
                    start=l;
                    len=r-l;
                }
                char d=s[l];
                l++;
                if(need.count(d)){
                    if(window[d]==need[d])
                        valid--;
                    window[d]--;
                }
            }
        }
        return len==INT_MAX? "":s.substr(start,len);
        
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_44583265/article/details/107682278