Skip to content

Commit 51aa9c5

Browse files
committed
feat: add solutions to lc problem: No.0676
No.0676.Implement Magic Dictionary
1 parent e3bcd3c commit 51aa9c5

File tree

6 files changed

+344
-149
lines changed

6 files changed

+344
-149
lines changed

solution/0600-0699/0676.Implement Magic Dictionary/README.md

Lines changed: 161 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,51 @@ magicDictionary.search("leetcoded"); // 返回 False
6161

6262
<!-- 这里可写通用的实现逻辑 -->
6363

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$。
6577

6678
<!-- tabs:start -->
6779

6880
### **Python3**
6981

7082
<!-- 这里可写当前语言的特殊实现逻辑 -->
7183

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+
72109
```python
73110
class MagicDictionary:
74111

@@ -77,17 +114,16 @@ class MagicDictionary:
77114
Initialize your data structure here.
78115
"""
79116

80-
def _patterns(self, word):
117+
def gen(self, word):
81118
return [word[:i] + '*' + word[i + 1:] for i in range(len(word))]
82119

83120
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))
87123

88124
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):
91127
return True
92128
return False
93129

@@ -102,32 +138,27 @@ class MagicDictionary:
102138

103139
<!-- 这里可写当前语言的特殊实现逻辑 -->
104140

105-
暴力法。直接遍历字典,判断是否存在一个单词与所要查找的单词之间只有一个字符不同,若是返回 true,否则返回 false。
106-
107141
```java
108142
class MagicDictionary {
109-
List<char[]> dict;
110-
/** Initialize your data structure here. */
143+
private String[] d;
144+
111145
public MagicDictionary() {
112-
dict = new ArrayList<>();
113-
}
114146

147+
}
148+
115149
public void buildDict(String[] dictionary) {
116-
for (String item : dictionary) {
117-
dict.add(item.toCharArray());
118-
}
150+
d = dictionary;
119151
}
120-
152+
121153
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()) {
125156
continue;
126157
}
127158
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;
131162
}
132163
}
133164
if (diff == 1) {
@@ -137,41 +168,45 @@ class MagicDictionary {
137168
return false;
138169
}
139170
}
140-
```
141171

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+
```
143179

144180
```java
145181
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<>();
148184

149185
/** Initialize your data structure here. */
150186
public MagicDictionary() {
151-
words = new HashSet<>();
152-
counter = new HashMap<>();
187+
153188
}
154189

155190
public void buildDict(String[] dictionary) {
156191
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);
160195
}
161196
}
162197
}
163198

164199
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))) {
168203
return true;
169204
}
170205
}
171206
return false;
172207
}
173208

174-
private List<String> patterns(String word) {
209+
private List<String> gen(String word) {
175210
List<String> res = new ArrayList<>();
176211
char[] chars = word.toCharArray();
177212
for (int i = 0; i < chars.length; ++i) {
@@ -197,32 +232,65 @@ class MagicDictionary {
197232
```cpp
198233
class MagicDictionary {
199234
public:
200-
/** Initialize your data structure here. */
235+
vector<string> d;
236+
201237
MagicDictionary() {
202238

203239
}
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() {
204270
271+
}
272+
205273
void buildDict(vector<string> dictionary) {
206274
for (string word : dictionary)
207275
{
208-
words.insert(word);
209-
for (string p : patterns(word)) ++counter[p];
276+
s.insert(word);
277+
for (string p : gen(word)) ++cnt[p];
210278
}
211279
}
212-
280+
213281
bool search(string searchWord) {
214-
for (string p : patterns(searchWord))
282+
for (string p : gen(searchWord))
215283
{
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;
217285
}
218286
return false;
219287
}
220288
221289
private:
222-
unordered_set<string> words;
223-
unordered_map<string, int> counter;
290+
unordered_set<string> s;
291+
unordered_map<string, int> cnt;
224292
225-
vector<string> patterns(string word) {
293+
vector<string> gen(string word) {
226294
vector<string> res;
227295
for (int i = 0; i < word.size(); ++i)
228296
{
@@ -247,37 +315,73 @@ private:
247315

248316
```go
249317
type MagicDictionary struct {
250-
words map[string]bool
251-
counter map[string]int
318+
d []string
252319
}
253320

254-
/** Initialize your data structure here. */
255321
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+
}
259343
}
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{}}
260364
}
261365

262366
func (this *MagicDictionary) BuildDict(dictionary []string) {
263367
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]++
267371
}
268372
}
269373
}
270374

271375
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]) {
274378
return true
275379
}
276380
}
277381
return false
278382
}
279383

280-
func patterns(word string) []string {
384+
func gen(word string) []string {
281385
var res []string
282386
for i := 0; i < len(word); i++ {
283387
res = append(res, word[:i]+"."+word[i+1:])

0 commit comments

Comments
 (0)