-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLCR064-ImplementMagicDictionary.go
More file actions
151 lines (133 loc) · 5.09 KB
/
LCR064-ImplementMagicDictionary.go
File metadata and controls
151 lines (133 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
// LCR 064. 实现一个魔法字典
// 设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 。
// 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于已构建的神奇字典中。
// 实现 MagicDictionary 类:
// MagicDictionary() 初始化对象
// void buildDict(String[] dictionary) 使用字符串数组 dictionary 设定该数据结构,dictionary 中的字符串互不相同
// bool search(String searchWord) 给定一个字符串 searchWord ,判定能否只将字符串中 一个 字母换成另一个字母,使得所形成的新字符串能够与字典中的任一字符串匹配。如果可以,返回 true ;否则,返回 false 。
// 示例:
// 输入
// inputs = ["MagicDictionary", "buildDict", "search", "search", "search", "search"]
// inputs = [[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
// 输出
// [null, null, false, true, false, false]
// 解释
// MagicDictionary magicDictionary = new MagicDictionary();
// magicDictionary.buildDict(["hello", "leetcode"]);
// magicDictionary.search("hello"); // 返回 False
// magicDictionary.search("hhllo"); // 将第二个 'h' 替换为 'e' 可以匹配 "hello" ,所以返回 True
// magicDictionary.search("hell"); // 返回 False
// magicDictionary.search("leetcoded"); // 返回 False
// 提示:
// 1 <= dictionary.length <= 100
// 1 <= dictionary[i].length <= 100
// dictionary[i] 仅由小写英文字母组成
// dictionary 中的所有字符串 互不相同
// 1 <= searchWord.length <= 100
// searchWord 仅由小写英文字母组成
// buildDict 仅在 search 之前调用一次
// 最多调用 100 次 search
import "fmt"
type MagicDictionary struct {
children [26]*MagicDictionary
isEnd bool
}
func Constructor() MagicDictionary {
return MagicDictionary{}
}
func (m *MagicDictionary) BuildDict(dictionary []string) {
for _, word := range dictionary {
m.insert(word)
}
}
func (m *MagicDictionary) insert(word string) {
cur := m
for _, ch := range word {
if cur.children[ch-'a'] == nil {
cur.children[ch-'a'] = &MagicDictionary{}
}
cur = cur.children[ch-'a']
}
cur.isEnd = true
}
func (m *MagicDictionary) Search(searchWord string) bool {
return dfs(m, searchWord, 0, 1)
}
func dfs(r *MagicDictionary, w string, i int, limit int) bool {
// base case
if limit < 0 {
return false
}
if i == len(w) {
return r.isEnd && limit == 0
}
ch := w[i] - 'a'
for c, t := range r.children { // iterate current node's all children
if t == nil {
continue
}
if c == int(ch) && dfs(t, w, i+1, limit) { // c == ch, represent don't need change.
return true
}
if c != int(ch) && dfs(t, w, i+1, limit-1) { // c != ch, represent consume one chance for change
return true
}
}
return false
}
type MagicDictionary1 struct {
data []string
}
func Constructor1() MagicDictionary1 {
return MagicDictionary1{}
}
func (this *MagicDictionary1) BuildDict(dictionary []string) {
this.data = dictionary
}
func (this *MagicDictionary1) Search(searchWord string) bool {
for _, d := range this.data {
c := 0
if len(d) != len(searchWord) { continue }
for i := 0; i < len(searchWord); i++ {
if searchWord[i] != d[i] { c++ }
}
if c == 1 { return true }
}
return false
}
/**
* Your MagicDictionary object will be instantiated and called as such:
* obj := Constructor();
* obj.BuildDict(dictionary);
* param_2 := obj.Search(searchWord);
*/
func main() {
// MagicDictionary magicDictionary = new MagicDictionary();
obj := Constructor()
fmt.Println(obj)
// magicDictionary.buildDict(["hello", "leetcode"]);
obj.BuildDict([]string{"hello", "leetcode"})
fmt.Println(obj)
// magicDictionary.search("hello"); // return False
fmt.Println(obj.Search("hello")) // false
// magicDictionary.search("hhllo"); // We can change the second 'h' to 'e' to match "hello" so we return True
fmt.Println(obj.Search("hhllo")) // true
// magicDictionary.search("hell"); // return False
fmt.Println(obj.Search("hell")) // false
// magicDictionary.search("leetcoded"); // return False
fmt.Println(obj.Search("leetcoded")) // false
obj1 := Constructor1()
fmt.Println(obj1)
// magicDictionary.buildDict(["hello", "leetcode"]);
obj1.BuildDict([]string{"hello", "leetcode"})
fmt.Println(obj1)
// magicDictionary.search("hello"); // return False
fmt.Println(obj1.Search("hello")) // false
// magicDictionary.search("hhllo"); // We can change the second 'h' to 'e' to match "hello" so we return True
fmt.Println(obj1.Search("hhllo")) // true
// magicDictionary.search("hell"); // return False
fmt.Println(obj1.Search("hell")) // false
// magicDictionary.search("leetcoded"); // return False
fmt.Println(obj1.Search("leetcoded")) // false
}