@@ -58,6 +58,12 @@ $dp[i]$ 表示前 $i$ 个字符组成的字符串 $s[0...i-1]$ 能否拆分成
58
58
59
59
时间复杂度 $O(n^2)$。
60
60
61
+ ** 方法二:前缀树 + 记忆化搜索**
62
+
63
+ 根据 $wordDict$ 构建前缀树 $trie$,然后枚举前缀 $s[ : i ] $ 作为第一个单词,若在 $trie$ 中,则递归搜索 $s[ i:] $。
64
+
65
+ 若存在满足条件的拆分方案,返回 $true$。
66
+
61
67
<!-- tabs:start -->
62
68
63
69
### ** Python3**
@@ -79,6 +85,42 @@ class Solution:
79
85
return dp[- 1 ]
80
86
```
81
87
88
+ ``` python
89
+ class Trie :
90
+ def __init__ (self ):
91
+ self .children = [None ] * 26
92
+ self .is_end = False
93
+
94
+ def insert (self , w ):
95
+ node = self
96
+ for c in w:
97
+ idx = ord (c) - ord (' a' )
98
+ if node.children[idx] is None :
99
+ node.children[idx] = Trie()
100
+ node = node.children[idx]
101
+ node.is_end = True
102
+
103
+ def search (self , w ):
104
+ node = self
105
+ for c in w:
106
+ idx = ord (c) - ord (' a' )
107
+ if node.children[idx] is None :
108
+ return False
109
+ node = node.children[idx]
110
+ return node.is_end
111
+
112
+ class Solution :
113
+ def wordBreak (self , s : str , wordDict : List[str ]) -> bool :
114
+ @cache
115
+ def dfs (s ):
116
+ return not s or any (trie.search(s[:i]) and dfs(s[i:]) for i in range (1 , len (s) + 1 ))
117
+
118
+ trie = Trie()
119
+ for w in wordDict:
120
+ trie.insert(w)
121
+ return dfs(s)
122
+ ```
123
+
82
124
### ** Java**
83
125
84
126
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -103,6 +145,66 @@ class Solution {
103
145
}
104
146
```
105
147
148
+ ``` java
149
+ class Trie {
150
+ Trie [] children = new Trie [26 ];
151
+ boolean isEnd;
152
+
153
+ void insert (String w ) {
154
+ Trie node = this ;
155
+ for (char c : w. toCharArray()) {
156
+ c -= ' a' ;
157
+ if (node. children[c] == null ) {
158
+ node. children[c] = new Trie ();
159
+ }
160
+ node = node. children[c];
161
+ }
162
+ node. isEnd = true ;
163
+ }
164
+
165
+ boolean search (String w ) {
166
+ Trie node = this ;
167
+ for (char c : w. toCharArray()) {
168
+ c -= ' a' ;
169
+ if (node. children[c] == null ) {
170
+ return false ;
171
+ }
172
+ node = node. children[c];
173
+ }
174
+ return node. isEnd;
175
+ }
176
+ }
177
+
178
+ class Solution {
179
+ private Trie trie = new Trie ();
180
+ private Map<String , Boolean > memo = new HashMap<> ();
181
+
182
+ public boolean wordBreak (String s , List<String > wordDict ) {
183
+ for (String w : wordDict) {
184
+ trie. insert(w);
185
+ }
186
+ return dfs(s);
187
+ }
188
+
189
+ private boolean dfs (String s ) {
190
+ if (memo. containsKey(s)) {
191
+ return memo. get(s);
192
+ }
193
+ if (" " . equals(s)) {
194
+ return true ;
195
+ }
196
+ for (int i = 1 ; i <= s. length(); ++ i) {
197
+ if (trie. search(s. substring(0 , i)) && dfs(s. substring(i))) {
198
+ memo. put(s, true );
199
+ return true ;
200
+ }
201
+ }
202
+ memo. put(s, false );
203
+ return false ;
204
+ }
205
+ }
206
+ ```
207
+
106
208
### ** C++**
107
209
108
210
``` cpp
@@ -129,6 +231,64 @@ public:
129
231
};
130
232
```
131
233
234
+ ```cpp
235
+ class Trie {
236
+ private:
237
+ vector<Trie*> children;
238
+ bool isEnd;
239
+ public:
240
+ Trie() : children(26), isEnd(false) {}
241
+
242
+ void insert(string word) {
243
+ Trie* node = this;
244
+ for (char c : word)
245
+ {
246
+ c -= 'a';
247
+ if (!node->children[c]) node->children[c] = new Trie();
248
+ node = node->children[c];
249
+ }
250
+ node->isEnd = true;
251
+ }
252
+
253
+ bool search(string word) {
254
+ Trie* node = this;
255
+ for (char c : word)
256
+ {
257
+ c -= 'a';
258
+ if (!node->children[c]) return false;
259
+ node = node->children[c];
260
+ }
261
+ return node->isEnd;
262
+ }
263
+ };
264
+
265
+ class Solution {
266
+ public:
267
+ Trie* trie = new Trie();
268
+ unordered_map<string, bool> memo;
269
+
270
+ bool wordBreak(string s, vector<string>& wordDict) {
271
+ for (auto w : wordDict) trie->insert(w);
272
+ return dfs(s);
273
+ }
274
+
275
+ bool dfs(string s) {
276
+ if (memo.count(s)) return memo[s];
277
+ if (s == "") return true;
278
+ for (int i = 1; i <= s.size(); ++i)
279
+ {
280
+ if (trie->search(s.substr(0, i)) && dfs(s.substr(i)))
281
+ {
282
+ memo[s] = true;
283
+ return true;
284
+ }
285
+ }
286
+ memo[s] = false;
287
+ return false;
288
+ }
289
+ };
290
+ ```
291
+
132
292
### ** Go**
133
293
134
294
``` go
@@ -152,6 +312,39 @@ func wordBreak(s string, wordDict []string) bool {
152
312
}
153
313
```
154
314
315
+ ``` go
316
+ type Trie struct {
317
+ children [26 ]*Trie
318
+ isEnd bool
319
+ }
320
+
321
+ func newTrie () *Trie {
322
+ return &Trie{}
323
+ }
324
+ func (this *Trie ) insert (word string ) {
325
+ node := this
326
+ for _ , c := range word {
327
+ c -= ' a'
328
+ if node.children [c] == nil {
329
+ node.children [c] = newTrie ()
330
+ }
331
+ node = node.children [c]
332
+ }
333
+ node.isEnd = true
334
+ }
335
+ func (this *Trie ) search (word string ) bool {
336
+ node := this
337
+ for _ , c := range word {
338
+ c -= ' a'
339
+ node = node.children [c]
340
+ if !node.isEnd {
341
+ return false
342
+ }
343
+ }
344
+ return true
345
+ }
346
+ ```
347
+
155
348
### ** C#**
156
349
157
350
``` cs
0 commit comments