Substring with Concatenation of All Words

carlblack發表於2019-05-11

每日演算法——leetcode系列


問題 Substring with Concatenation of All Words

Difficulty: Hard

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        
    }
};

翻譯

與所有單詞相關聯的字串

難度係數:困難
給定一個字串s和一些長度相同的單詞words,找出s的與words中所有單詞(words每個單詞只出現一次)串聯一起(words中組成串聯串的單詞的順序隨意)的字串匹配的所有起始索引,子串要與串聯串完全匹配,中間不能有其他字元。

思路

這題對我來說就是理解題意。
先把words中每個單詞,以words中每個單詞為key, 單詞出現的次數為value放入map表中
再在s中每次取三個來去map表找,如果找到則找下三個,如果沒找到,則s索引回溯到找到的第一個的索引 + 1。

程式碼


class Solution {
public:
    vector<int> findSubstring(string s, vector<string> &words) {
        
        vector<int> result;
        if (s.size() <= 0 || words.size() <= 0) {
            return result;
        }
        
        if (s.size() < words.size() * words[0].size()) {
            return result;
        }
        
        int m = static_cast<int>(s.size());
        int n = static_cast<int>(words.size());
        int l = static_cast<int>(words[0].size());
        
        unordered_map<string, int> wordMap;
        for (int i = 0; i < n; ++i) {
            if (wordMap.find(words[i]) != wordMap.end()) {
                wordMap[words[i]]++;
            } else {
                wordMap[words[i]] = 1;
            }
        }
        
        unordered_map<string, int> bakWordMap = wordMap;
        int fisrtIdnex = 0;
        for (int j = 0; j <= m - l;) {
            string word = s.substr(j, l);
            if (wordMap.find(word) == wordMap.end()) {
                j = ++fisrtIdnex;
                wordMap = bakWordMap;
                continue;
            }
            j += l;
            wordMap.at(word)--;
            if (wordMap.at(word) == 0) {
                wordMap.erase(word);
            }
            
            if (wordMap.empty()) {
                result.push_back(fisrtIdnex);
                wordMap = bakWordMap;
            }
        }
        
        return result;
    }

};

注: 這個本地測試可以, 但提交提示超時, 再考慮下其他的辦法。

相關文章