Minimum Window Substring leetcode

Minimum Window Substring


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).

For example,
S = "ADOBECODEBANC"
T = "ABC"

Minimum window is "BANC".

Note:
If there is no such window in S that covers all characters in T, return the emtpy string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

 题目的意思是说,要在S中找一个最短的子串,该子串包含了T中的所有字符,如上面所示   


用暴力法肯定是能够求出来的,思路为:用一个双重循环  从以S[0]开始的子串开始,求一个最短的,并用一个变量保存该值,然后求一个以S[1]开始的子串,并跟新变量的值。

下面介绍一种不用暴力法的算法


讲的是用一个hash表来存放字符串,然后动态的改变一个窗口,跟新而得到结果,这个有点类似

具体如下:

首先定义两个数组,一个为totalnumber[]表示T中字母所需要的次数  
一个为aredyfind[]  表示遍历过程中已经找到T中字母次数

totalnumber初始化为   遍历  T  然后     totalnumber[ T[ i ] ] ++    ,表示统计T中每个字母出现的次数



             初始用两个指针(i,start)  指向    S[0]   ,然后   i  一直 后面遍历,直到找到一个合适地址,该地址到start刚好是一个拥有所有T中字母的子串  (并不一定最优)

此时已经找到了一个以  start开始   的最小窗口      
缩减窗口:  将start 开始  但是 并不属于T中的字母删除   start++   直到  start处的字母属于T     ,当前已经找到一个最优的(satrt开始    i结束) 记录下来
然后start++    ,此时需要主要的是,由于上面已经找到一个当前最优的,那么  start++之后  必然会将一个属于T的字母删除了,  那么  需要i++来寻找那个字母了
所以又用i来遍历

代码  如下:

<span style="font-size:18px;">class Solution {
public:
    string minWindow(string S, string T) {
        
       
        int totalnumber[256]={0};
        int aredyfind[256]={0};
        
        int count=0;//用来表示当前已经找到的总字符,如果都找到,count为T.length()
        int i,start;
        int winstart=-1;
        int winend=S.length();
      
        for(i=0;i<T.size();i++)
        {
            totalnumber[T[i]]++;
        }
        
        for(i=0,start=0;i<S.size();i++)
        {
            if(totalnumber[S[i]]!=0) //这里表示字符S[i]属不属于T,如果不属于T那么直接跳过
            {
                aredyfind[S[i]]++;
                
                if(aredyfind[S[i]]<=totalnumber[S[i]])
                    count++;
                
                if(count==T.length()) //表示已经找到了一个合法的窗口
                {
                    while(totalnumber[S[start]]==0||aredyfind[S[start]]>totalnumber[S[start]])  //这里判断start处的字符属不属于T或者属于T但是重复出现了,两种情况都是要缩小窗口的
                    {
                        if(aredyfind[S[start]]!=0)
                            aredyfind[S[start]]--;
                        start++;
                    }
                    
                    if(winend-winstart>i-start)
                    {
                        winend=i;
                        winstart=start;
                    }
                    
                    aredyfind[S[start]]--;  //上面表示已经找到了一个start开始 i结束的当前最优,然后start++,此时必然有字母被删除了,所以回到开始i出循环,i往后遍历来寻找哪个被删除的字母
                    start++;
                    count--;
                    
                }
                
                
            }
                
        }
        
        return winstart==-1?"":S.substr(winstart,winend-winstart+1);
        
    }
};</span>


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值