76 Minimum Window Substring

https://leetcode.com/problems/minimum-window-substring/#/description

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 empty string"".

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

分析及代码

https://discuss.leetcode.com/topic/30941/here-is-a-10-line-template-that-can-solve-most-substring-problems

discuss有一种解法真的是太赞了,还给了一系列关于substring的general解法。

这题的c++代码是:

string minWindow(string s, string t) {
    vector<int> map(128,0);
    for(auto c: t) map[c]++;
    int counter=t.size(), begin=0, end=0, d=INT_MAX, head=0;
    while(end<s.size()){
        if(map[s[end++]]-->0) counter--; //in t
        while(counter==0){ //valid
            if(end-begin<d)  d=end-(head=begin);
            if(map[s[begin++]]++==0) counter++;  //make it invalid
        }  
    }
    return d==INT_MAX? "":s.substr(head, d);
}

Java是

public String minWindow(String s, String t) {
    int[] map = new int[128];
    int len = t.length();
    //统计template里面字母的次数
    for(int i = 0; i < len; i++) {
        map[t.charAt(i)]++;
    }
    int minLen = Integer.MAX_VALUE;
    int minStart = 0;
    int start = 0;
    int end = 0;
    int cnt = len;
    while(end < s.length()) {
        //对于非关键字母,对它的map里的计数-1
        //所以map里面的计数,如果是非关键字母,那么一定是小于或者等于零的,只有关键字母会大于0
        if(map[s.charAt(end++)]-- > 0) {
            cnt--;
        }
        //cnt == 0是所有关键字母都已经得到的情况,要做的是,从头开始退格,一直退到无法保持关键字母都存在的状况
        //退格要做的是:1.map相对的位置+1;2.向后移动start
        //如果退掉的是一个关键字母(因为此位非负),并且是一旦退掉这个就无法保持关键字母都在的状况(因为==0,而不是>0)
        //那么cnt++
        while(cnt == 0) {
            if(end - start < minLen) {
                minLen = end - start;
                minStart = start;
            }
            if(map[s.charAt(start++)]++ == 0) {
                cnt++;
            }
        }
    }
    //记得判断无法找到的情况
    return minLen == Integer.MAX_VALUE? "": s.substring(minStart, minStart + minLen);
}

简直棒呆。

还给了一个general的模板,可以做substring相关的题目

int findSubstring(string s){
    vector<int> map(128,0);
    int counter; // check whether the substring is valid
    int begin=0, end=0; //two pointers, one point to tail and one  head
    int d; //the length of substring

    for() { /* initialize the hash map here 初始化,比如计数之类的*/ }

    while(end<s.size()){

        if(map[s[end++]]-- ?){  /* modify counter here 改变cnt计数*/ }

        while(/* counter condition */){ 

             /* update d here if finding minimum*/

            //increase begin to make it invalid/valid again

            if(map[s[begin++]]++ ?){ /*modify counter here*/ }
        }  

        /* update d here if finding maximum*/
    }
    return d;
}

相关的题目,真的是一看就懂,包教包会包融会贯通:

  • [3. Longest Substring Without Repeating Characters]

原题连接:https://leetcode.com/problems/longest-substring-without-repeating-characters/\#/description

GitBook连接:

  • [Longest Substring with At Most Two Distinct Characters]()

原题连接:https://leetcode.com/problems/longest-substring-without-repeating-characters/\#/description

GitBook连接:

results matching ""

    No results matching ""