【leetcode】76. Minimum Window Substring 最小字符包含給定字符串的子串

1. 題目

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).windows

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.code

2. 思路

頭尾指針遍歷的思路。先遍歷尾指針,找到所有t覆蓋,而後移動頭指針找到最小的子串,比較是不是當前最小。
而後繼續移動一次頭指針後,去掉一個有效字符,從新開始一輪的循環。ip

爲了方便記錄是否已經找到所有的,對t用一個字符頻次數組來計數,找到一個隊頻次減一。爲了方便觀察數組是否所有覆蓋,另外維護一個有效減位的計數,當計數達到t的長度時就是一次徹底覆蓋。而後再查找最小覆蓋時,若是是無效字符,或者是有效但多出來頻次的字符都繼續跳過。string

3. 代碼

耗時:9msit

class Solution {
public:
    // 字符的值域空間是128,用128位的數組表示t中每一個字符出現的次數
    // 頭、尾兩個指針。尾指針一直向前掃描,直到覆蓋所有的t,假設指向i。
    // 而後頭指針向後移動,直到找到以i結尾的最小長度。
    // 記錄下當前的是不是最小子串。而後繼續尾指針、頭指針的這種掃描方式。
    string minWindow(string s, string t) {
        if (s.length() == 0 || t.length() == 0) { return ""; }
        int start = 0;
        int end = 0;
        int min_len = s.length() + 1;
        int cur_start = 0;
        int cur_end = 0;
        int t_freq[128];
        bool t_exist[128];
        bzero(t_freq, sizeof(t_freq));
        bzero(t_exist, sizeof(t_exist));
        for (int i = 0; i < t.length(); i++) {
            char ch = t[i];
            t_freq[ch]++;
            t_exist[ch] = true;
        }
        
        int ls = s.length();
        int lt = t.length();
        int cnt = 0;  // 記錄須要的字符出現過多少次,方便判斷是否已經包含所有的t
        while (cur_end < ls) {
            char ch = s[cur_end];
            if (!t_exist[ch]) { cur_end++; continue; }
            if (t_freq[ch] > 0) {
                cnt++;
            }
            t_freq[ch]--;
            cur_end++;
            if (cnt == lt) {
                while (cur_start < cur_end) {
                    char ch = s[cur_start];
                    if (!t_exist[ch]) { cur_start++; continue; }
                    if (t_freq[ch] < 0) { t_freq[ch]++; cur_start++; continue; }
                    else {
                        // find one candidate substr
                        int cur_len = cur_end - cur_start;
                        if (cur_len < min_len) {
                            min_len = cur_len;
                            start = cur_start;
                            end = cur_end;
                        }
                        cnt--;
                        t_freq[ch]++;
                        cur_start++;
                        break;
                    }
                }
            }
        }
        if (min_len <= ls) { return s.substr(start, min_len); }
        else { return ""; }
    }
};
相關文章
相關標籤/搜索