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>


Minimum Window Substring leetcode

上一篇:Optimization for Training Deep Models(3)


下一篇:Windows 2008 R2系统开机时如何不让Windows进行磁盘检测?