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.

 

这道题是编程之美中的寻找最短摘要。

方法一:直接暴力破解,时间复杂度为O(m*n2)

方法二:设置最短摘要起始位置winstart,最短摘要最终位置winend,winstart=0,winend = 0

1. 依次向后移动winend,每移动依次判断winstart~winend中的字串是否包含全部 T 串

2. 若第一次winend移动的位置,恰好使winstart~winend中的字符串包含全部T串(可能包含多个),这是依次向后移动winstart,直到到一个位置,恰好使第一次使winstart~winend中的字串恰好全部包含T串(因为再移动下一个位置,就不包含了),这是winstart~winend就是目前找到最短摘要之一。

3. 从1步骤开始,继续移动winend,寻找下一个最短摘要

注意:如果需要让时间复杂度达到O(n),那么必须空间换时间,需要使用哈希记录找到字符的个数。

代码如下:

 1 class Solution {
 2 public:
 3     string minWindow(string S, string T) {
 4         int mark[256] = {0};    //记录T中字符的种类及个数
 5         int cnt[256] = {0};     //统计winstart~winend中字符的种类及个数
 6         int hasfound = 0;       //统计winstart包含T中字符的个数,每种达到上限就不记录
 7         int winstart = 0, winend = 0;   //窗口的起始和终止位置
 8         int ansbegin = 0, ansend = 0x3fffffff;  //记录结果,0x3fffffff表示没有找到
 9         for(int i=0; i<T.length(); ++i) mark[ T[i] ]++; //预处理T中字符
10         while( winend < S.length() ) {
11             if( mark[ S[winend] ] ) {   //如果是T中的字符
12                 ++cnt[ S[winend] ];     //统计
13                 if( cnt[ S[winend] ] <= mark[ S[winend] ] ) ++hasfound; //注意,很关键,如果统计的个数小于等于T中该字符的个数
14                 if( hasfound == T.length() ) {  //说明这是winstart~winend字符串全部包含了T
15                     while( !mark[ S[winstart] ]     //后移winstart,直到找到恰好使winstart~winend包含T
16                         || cnt[ S[winstart] ] > mark[ S[winstart] ] ) {
17                         if( cnt[ S[winstart] ] > mark[ S[winstart] ] ) --cnt[ S[winstart] ];    //某字符的个数多于T中该字符的个数
18                         ++winstart;
19                     }
20                     if( winend-winstart < ansend-ansbegin ) {   //如果窗口更小,记录结果中
21                         ansbegin = winstart;
22                         ansend = winend;
23                     }
24                     --cnt[ S[winstart] ];   //winstart向后移动,改变相应的数据结构
25                     --hasfound;
26                     ++winstart;
27                 }
28             }
29             ++winend;
30         }
31         return ansend == 0x3fffffff ? string() : S.substr(ansbegin, ansend-ansbegin+1);
32     }
33 };

 

posted on 2014-09-05 10:18  bug睡的略爽  阅读(180)  评论(0编辑  收藏  举报

导航