• 【Minimum Window】cpp


    题目:

    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.

    代码:

    class Solution {
    public:
        string minWindow(string s, string t) {
                if (s.empty() && t.empty() ) return "";
                if (s.size()<t.size()) return "";
                const int ASCII_MAX = 256;
                // record how much times a char occurs in t
                int t_char_count[ASCII_MAX] = {0};
                for ( int i=0; i<t.size(); ++i ) { t_char_count[(int)t[i]]++; }
                // record how much times a char occurs in s
                int s_char_count[ASCII_MAX] = {0};
                // global min begin and end index for minimum interval
                int begin_min=-1, end_min=s.size();
                // local min begin ( no need to record local min end ,because it is 'i' )
                int begin = 0;
                int match_size = 0;
                for ( int i=0; i<s.size(); ++i )
                {
                    // current interval not match && current char in t
                    if ( t_char_count[(int)s[i]]>0 )
                    {
                        //cout << s[i] << ":" << t_char_count[s[i]] << endl;
                        s_char_count[(int)s[i]]++;
                        // if a char occurs more times in current interval s than in t, can not increase match_size
                        if ( s_char_count[(int)s[i]]<=t_char_count[(int)s[i]] ) match_size++;
                    }
                    if ( match_size==t.size() )
                    {
                        // move begin forward untill not match
                        while ( begin<=i )
                        {
                            // only address chars not in t
                            if ( s_char_count[(int)s[begin]]>0 )
                            {
                                if ( s_char_count[(int)s[begin]]-1<t_char_count[(int)s[begin]] ) 
                                {
                                    //cout << s_char_count[s[begin]] << endl; 
                                    match_size--;
                                    break;
                                }
                                s_char_count[(int)s[begin]]--;
                            }
                            begin++;
                        }
                        s_char_count[(int)s[begin]]--;
                        // update global min begin and end
                        if ( end_min-begin_min > i-begin ) { end_min = i; begin_min = begin; }
                        begin++;
                    }
                }
                if( end_min-begin_min>s.size() ) return "";
                return s.substr(begin_min,end_min-begin_min+1);
        }
    };

    tips:

    曾经以为这种题比较简答,实际上不带算法模板套路的题才是最费神的。

    这道题一开始的思路是记录t中每个字符最左边到哪最右边到哪,然后再云云;这个想法不太靠谱。

    如果是bruce force暴力解法,时间复杂度可以是O(n²)的:

    1. 遍历每个位置,以每个位置为中心,往左右走,直到包含所有的元素,取最短的。

    2. 取所有interval中最短的。

    可以AC的解法思路如下:

    1. 维护几个核心变量:

      a)t中每个字符出现了几次(t_char_count)

      b) s中当前区间里面,t中每个字符出现了几次(s_char_count)

      c) s当前区间是否满足包含t(match_size)

    2. 这道题思路很有趣:先找满足包含t的区间;一旦找到了这样的区间,再缩小这样的区间。

      缩减区间的方法:后面的指针保持不动,前面的指针往后移动,直到match_size < t.size(),则证明当前区间已经是最小的满足条件的区间了。

    3. 动态更新最小区间。

    主要参考:

    http://www.cnblogs.com/TenosDoIt/p/3461301.html

    http://fisherlei.blogspot.sg/2012/12/leetcode-minimum-window-substring.html

    ============================================

    第二次过这道题,静下心来码。

    class Solution {
    public:
        string minWindow(string s, string t) {
                int t_counts[256] = {0};
                int s_counts[256] = {0};
                for ( int i=0; i<t.size(); ++i ) t_counts[(int)t[i]]++;
                int matchTime = 0;
                int begin = -1;
                int end = s.size();
                int b = 0;
                for ( int i=0; i<s.size(); ++i )
                {
                    // only address character occurs in string t
                    if ( t_counts[(int)s[i]]>0 ) 
                    {
                        s_counts[(int)s[i]]++;
                        // after s_count add one change matchTime
                        if ( s_counts[(int)s[i]]<=t_counts[(int)s[i]] ) matchTime++;
                    }
                    // when there is a window, then minimisze it
                    if ( matchTime==t.size() )
                    {
                        while ( b<=i )
                        {
                            // only address charatcers occurs in string t
                            if ( s_counts[(int)s[b]]>0 )
                            {
                                // if move over 'begin then 'can not keep window
                                if ( s_counts[(int)s[b]]-1 < t_counts[(int)s[b]] )
                                {
                                    matchTime--;
                                    break;
                                }
                                s_counts[(int)s[b]]--;
                            }
                            b++;
                        }
                        if ( i-b < end-begin )
                        {
                            begin = b;
                            end = i;
                        }
                        s_counts[(int)s[b]]--;
                        b++;
                    }
                }
                if ( end-begin>s.size() ) return "";
                return s.substr(begin, end-begin+1);
        }
    };
  • 相关阅读:
    域控制器的常规卸载,Active Directory系列之十三
    理解域信任关系,Active Directory系列之十六
    什么是站点,Active Directory系列之十一
    域控制器的强制卸载,Active Directory系列之十四
    详解操作主机角色,Active Directory系列之九
    【转】MapControl和PageLayoutControl的同步
    AE的一些接口小记
    【转】centos linux 上flv/swf视频服务器架设
    lnmp配置超精简免费flv流媒体服务器笔记
    Flash game 遊戲修改 Cheat Engine 5.4 使用教學
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4561010.html
Copyright © 2020-2023  润新知