zoukankan      html  css  js  c++  java
  • 【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);
        }
    };
  • 相关阅读:
    mysql5.7.22安装步骤
    idea 配置http代理
    大话设计模式之类与类之间的关系读后感
    大话设计模式之工厂方法模式读后感
    rabbitmq+java入门(五)Topic
    rabbitmq+java入门(四)routing
    rabbitmq+java入门(二) 工作队列
    rabbitmq+java入门(三)exchange的使用
    rabbitmq+java入门(一)hello world
    idea+jrebel+springboot热部署
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4561010.html
Copyright © 2011-2022 走看看