@@ -61,14 +61,51 @@ magicDictionary.search("leetcoded"); // 返回 False
61
61
62
62
<!-- 这里可写通用的实现逻辑 -->
63
63
64
- 哈希表实现。
64
+ ** 方法一:直接遍历**
65
+
66
+ 对于 $buildDict$ 方法,直接将 $dictionary$ 赋给 $MagicDictionary$ 的成员变量 $d$。
67
+
68
+ 对于 $search$ 方法,遍历单词列表中的每个单词 $w$,依次与 $searchWord$ 进行比对,如果存在一个 $w$,满足 $w$ 与 $searchWord$ 恰好只有一个位置对应的字符不同,那么返回 $true$。
69
+
70
+ ** 方法二:哈希表 + 模式串**
71
+
72
+ 用哈希表 $s$ 存放 $dictionary$ 所有单词,同时生成每个单词的所有模式串,用哈希表 $cnt$ 存放。
73
+
74
+ 模式串的生成规则是:对于一个单词 $w$,我们将每个 $w[ i] $ 都替换成 $.$,最终得到一个模式串列表。例如,我们可以生成 $leet$ 的模式串列表为:$[ .eet, l.et, le.t, lee.] $。
75
+
76
+ 执行 $search$ 时,我们拿到 $searchWord$ 的模式串列表,然后判断列表中每个模式串 $p$ 是否在 $cnt$ 和 $s$ 中出现过。若 $cnt>1$ 或 $cnt=1$ 且 $searchWord$ 没在 $s$ 中出现过,说明找到了满足条件的单词,返回 $true$。
65
77
66
78
<!-- tabs:start -->
67
79
68
80
### ** Python3**
69
81
70
82
<!-- 这里可写当前语言的特殊实现逻辑 -->
71
83
84
+ ``` python
85
+ class MagicDictionary :
86
+
87
+ def __init__ (self ):
88
+ self .d = None
89
+
90
+ def buildDict (self , dictionary : List[str ]) -> None :
91
+ self .d = dictionary
92
+
93
+ def search (self , searchWord : str ) -> bool :
94
+ for w in self .d:
95
+ if len (w) != len (searchWord):
96
+ continue
97
+ diff = sum (a != b for a, b in zip (w, searchWord))
98
+ if diff == 1 :
99
+ return True
100
+ return False
101
+
102
+
103
+ # Your MagicDictionary object will be instantiated and called as such:
104
+ # obj = MagicDictionary()
105
+ # obj.buildDict(dictionary)
106
+ # param_2 = obj.search(searchWord)
107
+ ```
108
+
72
109
``` python
73
110
class MagicDictionary :
74
111
@@ -77,17 +114,16 @@ class MagicDictionary:
77
114
Initialize your data structure here.
78
115
"""
79
116
80
- def _patterns (self , word ):
117
+ def gen (self , word ):
81
118
return [word[:i] + ' *' + word[i + 1 :] for i in range (len (word))]
82
119
83
120
def buildDict (self , dictionary : List[str ]) -> None :
84
- self .words = set (dictionary)
85
- self .counter = Counter(
86
- p for word in dictionary for p in self ._patterns(word))
121
+ self .s = set (dictionary)
122
+ self .cnt = Counter(p for word in dictionary for p in self .gen(word))
87
123
88
124
def search (self , searchWord : str ) -> bool :
89
- for p in self ._patterns (searchWord):
90
- if self .counter [p] > 1 or (self .counter [p] == 1 and searchWord not in self .words ):
125
+ for p in self .gen (searchWord):
126
+ if self .cnt [p] > 1 or (self .cnt [p] == 1 and searchWord not in self .s ):
91
127
return True
92
128
return False
93
129
@@ -102,32 +138,27 @@ class MagicDictionary:
102
138
103
139
<!-- 这里可写当前语言的特殊实现逻辑 -->
104
140
105
- 暴力法。直接遍历字典,判断是否存在一个单词与所要查找的单词之间只有一个字符不同,若是返回 true,否则返回 false。
106
-
107
141
``` java
108
142
class MagicDictionary {
109
- List<char[]> dict ;
110
- /* * Initialize your data structure here. */
143
+ private String [] d ;
144
+
111
145
public MagicDictionary () {
112
- dict = new ArrayList<> ();
113
- }
114
146
147
+ }
148
+
115
149
public void buildDict (String [] dictionary ) {
116
- for (String item : dictionary) {
117
- dict. add(item. toCharArray());
118
- }
150
+ d = dictionary;
119
151
}
120
-
152
+
121
153
public boolean search (String searchWord ) {
122
- char [] target = searchWord. toCharArray();
123
- for (char [] item : dict) {
124
- if (item. length != target. length) {
154
+ for (String w : d) {
155
+ if (w. length() != searchWord. length()) {
125
156
continue ;
126
157
}
127
158
int diff = 0 ;
128
- for (int i = 0 ; i < target . length; i ++ ) {
129
- if (target[i] != item[i] ) {
130
- diff += 1 ;
159
+ for (int i = 0 ; i < w . length(); ++ i ) {
160
+ if (w . charAt(i) != searchWord . charAt(i) ) {
161
+ ++ diff ;
131
162
}
132
163
}
133
164
if (diff == 1 ) {
@@ -137,41 +168,45 @@ class MagicDictionary {
137
168
return false ;
138
169
}
139
170
}
140
- ```
141
171
142
- 哈希表。
172
+ /**
173
+ * Your MagicDictionary object will be instantiated and called as such:
174
+ * MagicDictionary obj = new MagicDictionary();
175
+ * obj.buildDict(dictionary);
176
+ * boolean param_2 = obj.search(searchWord);
177
+ */
178
+ ```
143
179
144
180
``` java
145
181
class MagicDictionary {
146
- private Set<String > words ;
147
- private Map<String , Integer > counter ;
182
+ private Set<String > s = new HashSet<> () ;
183
+ private Map<String , Integer > cnt = new HashMap<> () ;
148
184
149
185
/* * Initialize your data structure here. */
150
186
public MagicDictionary () {
151
- words = new HashSet<> ();
152
- counter = new HashMap<> ();
187
+
153
188
}
154
189
155
190
public void buildDict (String [] dictionary ) {
156
191
for (String word : dictionary) {
157
- words . add(word);
158
- for (String p : patterns (word)) {
159
- counter . put(p, counter . getOrDefault(p, 0 ) + 1 );
192
+ s . add(word);
193
+ for (String p : gen (word)) {
194
+ cnt . put(p, cnt . getOrDefault(p, 0 ) + 1 );
160
195
}
161
196
}
162
197
}
163
198
164
199
public boolean search (String searchWord ) {
165
- for (String p : patterns (searchWord)) {
166
- int cnt = counter . getOrDefault(p, 0 );
167
- if (cnt > 1 || (cnt == 1 && ! words . contains(searchWord))) {
200
+ for (String p : gen (searchWord)) {
201
+ int v = cnt . getOrDefault(p, 0 );
202
+ if (v > 1 || (v == 1 && ! s . contains(searchWord))) {
168
203
return true ;
169
204
}
170
205
}
171
206
return false ;
172
207
}
173
208
174
- private List<String > patterns (String word ) {
209
+ private List<String > gen (String word ) {
175
210
List<String > res = new ArrayList<> ();
176
211
char [] chars = word. toCharArray();
177
212
for (int i = 0 ; i < chars. length; ++ i) {
@@ -197,32 +232,65 @@ class MagicDictionary {
197
232
``` cpp
198
233
class MagicDictionary {
199
234
public:
200
- /** Initialize your data structure here. * /
235
+ vector<string > d;
236
+
201
237
MagicDictionary() {
202
238
203
239
}
240
+
241
+ void buildDict (vector<string > dictionary) {
242
+ d = move(dictionary);
243
+ }
244
+
245
+ bool search(string searchWord) {
246
+ for (auto&& w : d)
247
+ {
248
+ if (w.size() != searchWord.size()) continue;
249
+ int diff = 0;
250
+ for (int i = 0; i < w.size(); ++i) diff += w[ i] != searchWord[ i] ;
251
+ if (diff == 1) return true;
252
+ }
253
+ return false;
254
+ }
255
+ };
256
+
257
+ /**
258
+ * Your MagicDictionary object will be instantiated and called as such:
259
+ * MagicDictionary* obj = new MagicDictionary();
260
+ * obj->buildDict(dictionary);
261
+ * bool param_2 = obj->search(searchWord);
262
+ * /
263
+ ```
264
+
265
+ ```cpp
266
+ class MagicDictionary {
267
+ public:
268
+ /** Initialize your data structure here. */
269
+ MagicDictionary() {
204
270
271
+ }
272
+
205
273
void buildDict(vector<string> dictionary) {
206
274
for (string word : dictionary)
207
275
{
208
- words .insert(word);
209
- for (string p : patterns (word)) ++counter [ p] ;
276
+ s .insert(word);
277
+ for (string p : gen (word)) ++cnt [p];
210
278
}
211
279
}
212
-
280
+
213
281
bool search(string searchWord) {
214
- for (string p : patterns (searchWord))
282
+ for (string p : gen (searchWord))
215
283
{
216
- if (counter [p] > 1 || (counter [p] == 1 && !words .count(searchWord))) return true;
284
+ if (cnt [p] > 1 || (cnt [p] == 1 && !s .count(searchWord))) return true;
217
285
}
218
286
return false;
219
287
}
220
288
221
289
private:
222
- unordered_set<string > words ;
223
- unordered_map<string, int> counter ;
290
+ unordered_set<string> s ;
291
+ unordered_map<string, int> cnt ;
224
292
225
- vector<string> patterns (string word) {
293
+ vector<string> gen (string word) {
226
294
vector<string> res;
227
295
for (int i = 0; i < word.size(); ++i)
228
296
{
@@ -247,37 +315,73 @@ private:
247
315
248
316
``` go
249
317
type MagicDictionary struct {
250
- words map[string]bool
251
- counter map[string]int
318
+ d []string
252
319
}
253
320
254
- /** Initialize your data structure here. */
255
321
func Constructor () MagicDictionary {
256
- return MagicDictionary{
257
- words: make(map[string]bool),
258
- counter: make(map[string]int),
322
+ return MagicDictionary{[]string {}}
323
+ }
324
+
325
+ func (this *MagicDictionary ) BuildDict (dictionary []string ) {
326
+ this.d = dictionary
327
+ }
328
+
329
+ func (this *MagicDictionary ) Search (searchWord string ) bool {
330
+ for _ , w := range this.d {
331
+ if len (w) != len (searchWord) {
332
+ continue
333
+ }
334
+ diff := 0
335
+ for i := range w {
336
+ if w[i] != searchWord[i] {
337
+ diff++
338
+ }
339
+ }
340
+ if diff == 1 {
341
+ return true
342
+ }
259
343
}
344
+ return false
345
+ }
346
+
347
+ /* *
348
+ * Your MagicDictionary object will be instantiated and called as such:
349
+ * obj := Constructor();
350
+ * obj.BuildDict(dictionary);
351
+ * param_2 := obj.Search(searchWord);
352
+ */
353
+ ```
354
+
355
+ ``` go
356
+ type MagicDictionary struct {
357
+ s map [string ]bool
358
+ cnt map [string ]int
359
+ }
360
+
361
+ /* * Initialize your data structure here. */
362
+ func Constructor () MagicDictionary {
363
+ return MagicDictionary{map [string ]bool {}, map [string ]int {}}
260
364
}
261
365
262
366
func (this *MagicDictionary ) BuildDict (dictionary []string ) {
263
367
for _ , word := range dictionary {
264
- this.words [word] = true
265
- for _, p := range patterns (word) {
266
- this.counter [p]++
368
+ this.s [word] = true
369
+ for _ , p := range gen (word) {
370
+ this.cnt [p]++
267
371
}
268
372
}
269
373
}
270
374
271
375
func (this *MagicDictionary ) Search (searchWord string ) bool {
272
- for _, p := range patterns (searchWord) {
273
- if this.counter [p] > 1 || (this.counter [p] == 1 && !this.words [searchWord]) {
376
+ for _ , p := range gen (searchWord) {
377
+ if this.cnt [p] > 1 || (this.cnt [p] == 1 && !this.s [searchWord]) {
274
378
return true
275
379
}
276
380
}
277
381
return false
278
382
}
279
383
280
- func patterns (word string) []string {
384
+ func gen (word string ) []string {
281
385
var res []string
282
386
for i := 0 ; i < len (word); i++ {
283
387
res = append (res, word[:i]+" ." +word[i+1 :])
0 commit comments