Replace Words 單詞替換
阿新 • • 發佈:2018-12-13
在英語中,我們有一個叫做 詞根
(root)的概念,它可以跟著其他一些片語成另一個較長的單詞——我們稱這個詞為 繼承詞
(successor)。例如,詞根an
,跟隨著單詞 other
(其他),可以形成新的單詞 another
(另一個)。
現在,給定一個由許多詞根組成的詞典和一個句子。你需要將句子中的所有繼承詞
用詞根
替換掉。如果繼承詞
有許多可以形成它的詞根
,則用最短的詞根替換它。
你需要輸出替換之後的句子。
示例 1:
輸入: dict(詞典) = ["cat", "bat", "rat"] sentence(句子) = "the cattle was rattled by the battery" 輸出:"the cat was rat by the bat"
注:
- 輸入只包含小寫字母。
- 1 <= 字典單詞數 <=1000
- 1 <= 句中詞語數 <= 1000
- 1 <= 詞根長度 <= 100
- 1 <= 句中詞語長度 <= 1000
思路:這道題用單詞字首樹來做,但是題目要求如果有多個解,保留最短的單詞長度即可,所以有兩個優化的地方:
1:每次通過bool變數的isRoot來匹配是否存在最短路徑,例如cat和cata同時作為詞根進入字首樹,那麼字首樹只會構造出cat而不會構造出cata(嚴格來說和cat和cata誰先進入有關係,但是最終的結果是通過isRoot變數來保證在查詢匹配字串時只匹配cat)
2:如果沒有找到以當前單詞為詞根的字串,那麼游標會持續向右移,所以這樣可以保證時間複雜度是O(1)
參考程式碼:
class Solution { public: class trie { private: bool isRoot=false; trie* l[26] = {}; public: void insert(string& word, int start, int end) { isRoot |= (start == end); if (!isRoot) { if (l[word[start] - 'a'] == nullptr) l[word[start] - 'a'] = new trie(); l[word[start] - 'a']->insert(word, start + 1, end); } } int calculate(string& word, int start, int ch, int end) { if ((start+ch)==end || word[start+ch]==' ' || isRoot) return ch; if (l[word[start + ch] - 'a'] == nullptr) { //沒有找到root while ((start + ch) < end && word[start + ch] != ' ') ch++; return ch; } return l[word[start + ch] - 'a']->calculate(word, start, ch + 1, end); } }; string replaceWords(vector<string>& dict, string sentence) { trie t; string res; for (auto &tmp : dict) t.insert(tmp,0,tmp.size()); for (int i = 0; i < sentence.size();) { if (sentence[i] == ' ') res += sentence[i++]; int tmp = t.calculate(sentence, i, 0, sentence.size()); res += sentence.substr(i, tmp); for (i += tmp; i < sentence.size() && sentence[i] != ' ';) i++; } return res; } };