時間複雜度:O(d+n⋅m),其中 d 是 dictionary 的字元總數,n 是句子中的單字數量,m 是每個單字的最大長度。
構建雜湊表的時間複雜度為 O(d)。
在最壞情況下,我們需要對每個單字檢查其所有前綴,因此時間複雜度為 O(n⋅m)。不過嚴格來說應該是 wi∈words∑wi2 ,其中 wi 是第 i 個單字的長度。
空間複雜度:O(d+s),其中 s 為字串 sentence 的長度
我們需要額外的空間來存儲字根集合。
分割後的單字列表需要 O(s) 的空間。
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defreplaceWords(self, dictionary: List[str], sentence: str) -> str: d = set(dictionary) # hash set ans = [] for word in sentence.split(" "): for i inrange(1, len(word)+1): if word[:i] in d: ans.append(word[:i]) break else: ans.append(word) return" ".join(ans)
classSolution { public: string replaceWords(vector<string>& dictionary, string sentence){ int n = sentence.size(), i = 0, st; unordered_set<string> dict; for (auto& word : dictionary) dict.insert(word); string ans, word; // 分組循環 while (i < n) { st = i; while (i < n && sentence[i] != ' ') i++; word = sentence.substr(st, i - st); i++; // Process word for (int j = 1; j <= word.size(); j++) { if (dict.count(word.substr(0, j))) { // find prefix word = word.substr(0, j); break; } } if (ans.empty()) ans = word; else ans += " " + word; } return ans; } };
方法二:字典樹(Trie)
但在方法一的過程中,對於每個單詞,我們需要對其所有前綴進行查找,這樣的時間複雜度是 O(n×m),其中 n 是句子中的單字數量,m 是每個單字的最大長度。這樣的效率並不高。
classNode: # Trie def__init__(self): self.child = [None] * 26 self.isEnd = False classSolution: defreplaceWords(self, dictionary: List[str], sentence: str) -> str: root = Node() for word in dictionary: cur = root for ch in word: idx = ord(ch) - ord("a") if cur.child[idx] isNone: cur.child[idx] = Node() cur = cur.child[idx] cur.isEnd = True ans = [] for word in sentence.split(" "): cur = root for i, ch inenumerate(word): idx = ord(ch) - ord("a") cur = cur.child[idx] if cur isNone: # no prefix, case 1 ans.append(word) break if cur.isEnd: # find prefix ans.append(word[:i+1]) break else: # no prefix, case 2 ans.append(word) return" ".join(ans)
classSolution2 { public: string replaceWords(vector<string>& dictionary, string sentence){ Node *root = newNode(); for (auto& word : dictionary) { Node* cur = root; for (auto& ch : word) { if (!cur->child[ch - 'a']) cur->child[ch - 'a'] = newNode(); cur = cur->child[ch - 'a']; } cur->isEnd = true; } int n = sentence.size(), i = 0, st; string ans, word; while (i < n) { st = i; while (i < n && sentence[i] != ' ') i++; word = sentence.substr(st, i - st); i++; // Process word Node* cur = root; for (int j = 0; j < word.size(); j++) { if (!cur->child[word[j] - 'a']) break; cur = cur->child[word[j] - 'a']; if (cur->isEnd) { word = word.substr(0, j + 1); break; } } if (ans.empty()) ans = word; else ans += " " + word; } return ans; } };
寫在最後
Cover photo is generated by @ゴリラの素材屋さん, thanks for their work!