leetcode 30. Substring with Concatenation of All Words

sliding window來優化這個遍歷過程。保證sliding window裏面的單詞都是候選詞向量裏面的詞,而且每個候選詞只能出現一次。這樣的話當sliding window裏面的大小與候選詞向量的單詞數相等的時候,就說明sliding window就是一種合理的答案。用一個哈希表記錄候選詞向量裏每個詞的個數,在遍歷原字符串的時候,如果下一個單詞是在候選詞向量裏面的,而且在sliding window裏面出現的次數沒有超過哈希表記錄的次數,就可以擴大這個sliding window這種是最理想的情況,一直增大sliding window,直到這個sliding window的大小等於候選詞的數量,就把這時候的start index記錄下來。但是事情不會總是這麼完美的,當遇到不是候選詞的單詞,說明sliding windowstart index不是一種合理答案,就要清空這個sliding window並且sliding windowstart index向右移一位;還有一種情況是跟單詞的次數有關的,當遇到一個候選詞w,但是sliding window裏面的w出現的次數已經超過了哈希表記錄的次數,說明這時的sliding window不是一種合理答案,不能繼續擴大sliding window,但這時候是不是和上面的這種情況一樣,直接清空sliding window,並右移start index呢?如果將這兩種情況合在一起考慮的話,就跟最樸素的查找是一樣的了。

這裏利用sliding window,每一次遍歷都要考慮到直到原字符串最後一個字符的所有的情況。所以startInd = 0startInd = wordLen的分詞結果是相同的,startInd = wordLen裏所有的合理情況在startInd = 0已經被涵蓋了。所以外循環的大小隻是wordLen - 1這樣的話,當遇到一個候選詞w,但是sliding window裏面的w出現的次數已經超過了哈希表記錄的次數,說明startInd已經不可能是一種合理答案了,但是startInd + x * wordLen還有可能是一種合理答案,這時候要把sliding window的左邊界往右移,縮小sliding window的大小。

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        if (words.size() == 0 || s == "") {
            return {};
        }
        vector<int> resultVec;
        unordered_map<string, int> hashTable;
        for (int i = 0; i < words.size(); i++) {
            if (hashTable.find(words[i]) == hashTable.end()) {
                hashTable[words[i]] = 0;
            }
            hashTable[words[i]]++;
        }
        int wordLen = int(words[0].length()), wordCount = 0, vectorSize = int(words.size());
        unordered_map<string, int> counterTable;
        for (int i = 0; i < wordLen; i++) {
            int startInd = i;
            counterTable.clear();
            wordCount = 0;
            for (int j = startInd; j < s.length(); j += wordLen) {
                string checkStr = s.substr(j, wordLen);
                if (hashTable.find(checkStr) == hashTable.end()) {
                    counterTable.clear();
                    wordCount = 0;
                    continue;
                } else {
                    if (counterTable.find(checkStr) == counterTable.end()) {
                        counterTable[checkStr] = 0;
                    }
                    counterTable[checkStr]++;
                    wordCount++;
                    while (counterTable[checkStr] > hashTable[checkStr]) {
                        string startSub = s.substr(j - (wordCount - 1) * wordLen, wordLen);
                        counterTable[startSub]--;
                        wordCount--;
                        if (counterTable[startSub] == 0) {
                            counterTable.erase(startSub);
                        }
                    }
                    if (wordCount == vectorSize) {
                        resultVec.push_back(j - (wordCount - 1) * wordLen);
                    }
                }
            }
        }
        return resultVec;
    }
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章