最小覆盖子串(滑动窗口)

题目描述
给出两个字符串 S 和 T,要求在O(n)O(n)的时间复杂度内在 S 中找出最短的包含 T 中所有字符的子串。
例如:
S =“XDOYEZODEYXNZ”
T =“XYZ”
找出的最短子串为"YXNZ"

注意:
如果 S 中没有包含 T 中所有字符的子串,返回空字符串 “”;
满足条件的子串可能有很多,但是题目保证满足条件的最短的子串唯一。

示例1
输入 “XDOYEZODEYXNZ”,“XYZ”
返回值 “YXNZ”

题解:

----j--------i-------
当 i 向后移动时,j 只能向后移动,不能向前移动,原因:假设 区间[ j,i ] 已经包含所需要的字符,j 向前移动依旧包含,题目要求解的是最小的,因此 j 无法向前移动,可以使用滑动窗口,两个指针同步移j动。

  • j 何时向后移动:当区间中的j 指向的字符已经包含且大于 T 中该字符的个数,此时需要向后移动。
  • 如何知道 T 中特定字符个数且随时获取呢?选用hash 来存储 T 中的字符及其数量的对应关系。 区间中的字符的数量也需要使用hash来存储。
  • 还需要一个变量来记录区间中有效的在T中的元素的个数。如果区间中cnt个数已经等于T中的元素总数,那么需要更新res,由于需要最小的覆盖子串,因此需要更新时需要判断此时区间覆盖长度是否小于原先的覆盖子串的长度。
class Solution {
public:
    string minWindow(string S, string T) {
        // write code heres
        unordered_map<char,int> hs,ht;
        for(auto x:T) ht[x]++;
        string res;
        int cnt=0;
        for(int i=0,j=0;i<S.size();i++)
        {
            hs[S[i]]++;
            if(hs[S[i]]<=ht[S[i]]) cnt++;
            while( hs[S[j]] > ht[S[j]]) hs[S[j++]]--;
            if(cnt==T.size())
            {
                if(res.empty()||i-j+1 < res.size())
                    res=S.substr(j,i-j+1);
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值