Minimum Window Substring

406 篇文章 0 订阅
406 篇文章 0 订阅

1,题目要求

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

Example:
Input: S = "ADOBECODEBANC", T = "ABC"
Output:"BANC"

Note:

  • If there is no such window in S that covers all characters in T, return the empty string “”.
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

给定一个字符串S和一个字符串T,找到S中的最小窗口,它将包含复杂度为O(n)的T中的所有字符。

2,题目思路

对于这道题,要求求出在字符串S中包含字符串T所有字符的子串最小长度。

因为题目要求需要在O(n)的时间范围内完成,因此,我们可以定义一个滑动窗口在S上移动,用这种策略来找最短的子串。

对于字符是否完全出现问题,一般我们都是使用的hash表来实现字母与出现次数的映射。直接以ASCII为下标是一种比较方便的技巧。

其次,在遍历的过程中,我们会统计从当前开始位置到遍历位置,s的子串中是否包含了t的所有字符。
如果包含了所有的字符,那么:
1,我们需要计算当前合法子串的长度是否更短,如果更短,就更新结果,并记录当前子串的开始位置。
2,将之前hash为了计算而进行减一操作的字符恢复原值,并更新下一轮遍历的开始位置。

附带LeetCode中的discussion:
Here is a 10-line template that can solve most ‘substring’ problems

3,代码实现

static const auto s = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();

class Solution {
public:
    string minWindow(string s, string t) {
        vector<int> hashMap(128, 0);
        for(auto &c : t)
            hashMap[c]++;
        
        int counter = t.size();
        int begin = 0, end = 0;
        int resLen = INT_MAX, resHead = 0;
        
        while(end < s.size()){
            //说明当前字符在t中
            if(hashMap[s[end++]]-- > 0)
                counter--;
            //找到了一个结果
            while(counter == 0){
                if(end - begin < resLen){
                    resLen = end - begin;
                    resHead = begin;
                }
                //将hashMap恢复,并更新开始位置
                if(hashMap[s[begin++]]++ == 0)
                    counter++;
            }            
        }
        return resLen == INT_MAX? "" : s.substr(resHead, resLen);

    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值