Leetcode 每日一題 76. 最小覆蓋子串

76. 最小覆蓋子串

解題思路:

本題採用滑動窗口的方法(事實證明,這效率有些低)。

  1. 首先定義兩個指針left和right,分別指向主串的兩邊位置
  2. 定義兩個hashTable ,一個用來記錄主串當前每個字符映射的個數,另一個是記錄模式串每個字符的個數
  3. 模式串每個字符對應的個數首先都要映射到一個hash表中,這個主要是用來當作判斷的一個籌碼。
  4. 遍歷主串中每一個字符,此時要對滑動窗口進行調整,每一個字符加進來,要擴大當前窗口的右指針,然後判斷當前窗口裏是否包含每一個模式串元素,如果包含,則嘗試縮小左指針,以減小窗口大小
  5. 最後要對邊界情況進行判斷,如模式串的字符個數比主串都少,和主串只有一個字符的情況
源代碼:
class Solution {
private:
    unordered_map<char, int> ori, cnt;
public:
    string deal_str(string s){
        int resl = 0;
        for(const auto &tmp : s){
            if(ori.find(tmp) != ori.end()) return s.substr(resl, s.length() - resl);
        }
        return s;
    }
    bool check(){
        for(const auto &tmp : ori){
            if(cnt[tmp.first] < tmp.second) return false;
        }
        return true;
    }
    string minWindow(string s, string t) {
        // 首先將匹配串的所有字符映射到hashtable中
        for(const auto &tmp_char : t){
            ori[tmp_char] ++;
        }
        // 這裏抖個機靈處理一下原始字符串,
        // 不過我處理的好像不太對,沒個屌用。。
        s = deal_str(s);
        // 定義兩個指針 這裏resl一定要定義爲-1,因爲如果主串和匹配串都是一個字符,則其他數字就無法判斷了。
        int l = 0, r = 0, resl = -1, min_len = INT_MAX;
        // 將右指針向外擴張
        while(r < s.length()){
            // 先將字符壓入hash中
            cnt[s[r]] ++;
            // 將左指針向右收縮
            while(check() && l <= r){
                if(min_len > r-l+1){
                    min_len = r-l+1;
                    resl = l;
                }
                cnt[s[l]] --;
                l ++;
            }
            r ++;
        }

        return resl == -1 ?  "" : s.substr(resl, min_len);
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章