最小窗口子字符串 LEETCODE 探索提升遇到的第一个困难的题目。

最小窗口子字符串

给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。

示例:

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

说明:

  • 如果 S 中不存这样的子串,则返回空字符串 ""
  • 如果 S 中存在这样的子串,我们保证它是唯一的答案

原题地址

问题已经很具体了,分析ac代码。

class Solution {
public:
  string minWindow(string s, string t) {
        vector<int> map(128,0);
        for(auto c: t) map[c]++;
        int counter = t.size(), begin = 0, end = 0, d = INT_MAX, head = 0;
        while(end<s.size()){
            if(map[s[end++]]-- > 0) counter--; //in t
            while(counter == 0){ //valid
                if(end - begin < d)  d = end - (head = begin);
                if(map[s[begin++]]++ == 0) counter++;  //make it invalid
            }  
        }
        return d==INT_MAX? "":s.substr(head, d);
    }
};

定义ascII 128 字符hash 是在字符串处理中,检测是否出现过的常用做法。 

通过第一行第二行代码确定了需要包含的字符范围;我最初的想法是建立一个unorder_map 实质是一样的。 

对于字符串处理这种方法更经济直观。 

对于截取子串来说。 在 counter 等于零的时候 , 

end  到 begin 一定是一条包含子串,这个时候 需要判断是否是最短的子串。 

长度就等 end - begin。先记录下来。 然后在改变原先的map 现在需要的是继续搜索下一串子串,头指针前移hash自加。但是问题是这样不就不知道子串是不是包含t 了么。依然是知道的。注意看if(map[s[end++]]-- > 0) counter--; //in t 这个代码。在这里map中原来为1的变成了零,但是原来没有的字符变成的是-1;在哈希中就实现了不包含的字符串就跳过了。当等于零的点在后一个循环中又出现时,说明包含的字符出现了,那么给他自加到1,而没有包含的字符从-1自加到零。counter 在自加1。跳出内层循环。同时相当于扔掉最早的出现的一个包含字符。尾部继续搜索最先出现的这个字符。

整个算法拆开来就是这样。 其中关键的有几点 

主循环只走一遍,end 在循环内无脑自加,同时利用hash检测是否包含。同时又标记是否遍历过。 记录当前查找进度

内层循环 主要功能 第一记录当前找到的字符串长度,与位置。第二,丢掉最先找到的包含字符,让外循环继续寻找这个字符在尾部。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值