Skip to content

Commit 956ff27

Browse files
committed
feat: update leetcode solutions: No.0208. Implement Trie (Prefix Tree)
1 parent 177ac8b commit 956ff27

File tree

4 files changed

+329
-66
lines changed

4 files changed

+329
-66
lines changed

solution/0200-0299/0208.Implement Trie (Prefix Tree)/README.md

+131-2
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,151 @@ trie.search(&quot;app&quot;); // 返回 true</pre>
2929

3030
<!-- 这里可写通用的实现逻辑 -->
3131

32+
前缀树每个节点包括两部分:
33+
34+
1. 指向子节点的指针数组 children,对于本题而言,数组长度为 26,即小写英文字母的数量。`children[0]` 对应小写字母 a,...,`children[25]` 对应小写字母 z。
35+
1. 布尔字段 `isEnd`,表示该节点是否为字符串的结尾。
36+
37+
### 1. 插入字符串
38+
39+
我们从字典树的根开始,插入字符串。对于当前字符对应的子节点,有两种情况:
40+
41+
- 子节点存在。沿着指针移动到子节点,继续处理下一个字符。
42+
- 子节点不存在。创建一个新的子节点,记录在 `children` 数组的对应位置上,然后沿着指针移动到子节点,继续搜索下一个字符。
43+
44+
重复以上步骤,直到处理字符串的最后一个字符,然后将当前节点标记为字符串的结尾。
45+
46+
### 2. 查找前缀
47+
48+
我们从字典树的根开始,查找前缀。对于当前字符对应的子节点,有两种情况:
49+
50+
- 子节点存在。沿着指针移动到子节点,继续搜索下一个字符。
51+
- 子节点不存在。说明字典树中不包含该前缀,返回空指针。
52+
53+
重复以上步骤,直到返回空指针或搜索完前缀的最后一个字符。
54+
55+
若搜索到了前缀的末尾,就说明字典树中存在该前缀。此外,若前缀末尾对应节点的 `isEnd` 为真,则说明字典树中存在该字符串。
56+
3257
<!-- tabs:start -->
3358

3459
### **Python3**
3560

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

3863
```python
39-
64+
class Trie:
65+
66+
def __init__(self):
67+
"""
68+
Initialize your data structure here.
69+
"""
70+
self.children = [None] * 26
71+
self.is_end = False
72+
73+
def insert(self, word: str) -> None:
74+
"""
75+
Inserts a word into the trie.
76+
"""
77+
node = self
78+
for c in word:
79+
index = ord(c) - ord("a")
80+
if node.children[index] is None:
81+
node.children[index] = Trie()
82+
node = node.children[index]
83+
node.is_end = True
84+
85+
def search(self, word: str) -> bool:
86+
"""
87+
Returns if the word is in the trie.
88+
"""
89+
node = self._search_prefix(word)
90+
return node is not None and node.is_end
91+
92+
def startsWith(self, prefix: str) -> bool:
93+
"""
94+
Returns if there is any word in the trie that starts with the given prefix.
95+
"""
96+
node = self._search_prefix(prefix)
97+
return node is not None
98+
99+
def _search_prefix(self, prefix: str):
100+
node = self
101+
for c in prefix:
102+
index = ord(c) - ord("a")
103+
if node.children[index] is None:
104+
return None
105+
node = node.children[index]
106+
return node
107+
108+
# Your Trie object will be instantiated and called as such:
109+
# obj = Trie()
110+
# obj.insert(word)
111+
# param_2 = obj.search(word)
112+
# param_3 = obj.startsWith(prefix)
40113
```
41114

42115
### **Java**
43116

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

46119
```java
47-
120+
class Trie {
121+
private Trie[] children;
122+
private boolean isEnd;
123+
124+
/** Initialize your data structure here. */
125+
public Trie() {
126+
children = new Trie[26];
127+
isEnd = false;
128+
}
129+
130+
/** Inserts a word into the trie. */
131+
public void insert(String word) {
132+
Trie node = this;
133+
for (int i = 0; i < word.length(); ++i) {
134+
char c = word.charAt(i);
135+
int index = c - 'a';
136+
if (node.children[index] == null) {
137+
node.children[index] = new Trie();
138+
}
139+
node = node.children[index];
140+
}
141+
node.isEnd = true;
142+
}
143+
144+
/** Returns if the word is in the trie. */
145+
public boolean search(String word) {
146+
Trie node = searchPrefix(word);
147+
return node != null && node.isEnd;
148+
}
149+
150+
/** Returns if there is any word in the trie that starts with the given prefix. */
151+
public boolean startsWith(String prefix) {
152+
Trie node = searchPrefix(prefix);
153+
return node != null;
154+
}
155+
156+
private Trie searchPrefix(String prefix) {
157+
Trie node = this;
158+
for (int i = 0; i < prefix.length(); ++i) {
159+
char c = prefix.charAt(i);
160+
int index = c - 'a';
161+
if (node.children[index] == null) {
162+
return null;
163+
}
164+
node = node.children[index];
165+
}
166+
return node;
167+
}
168+
}
169+
170+
/**
171+
* Your Trie object will be instantiated and called as such:
172+
* Trie obj = new Trie();
173+
* obj.insert(word);
174+
* boolean param_2 = obj.search(word);
175+
* boolean param_3 = obj.startsWith(prefix);
176+
*/
48177
```
49178

50179
### **...**

solution/0200-0299/0208.Implement Trie (Prefix Tree)/README_EN.md

+106-2
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,117 @@ trie.search(&quot;app&quot;); // returns true
4242
### **Python3**
4343

4444
```python
45-
45+
class Trie:
46+
47+
def __init__(self):
48+
"""
49+
Initialize your data structure here.
50+
"""
51+
self.children = [None] * 26
52+
self.is_end = False
53+
54+
def insert(self, word: str) -> None:
55+
"""
56+
Inserts a word into the trie.
57+
"""
58+
node = self
59+
for c in word:
60+
index = ord(c) - ord("a")
61+
if node.children[index] is None:
62+
node.children[index] = Trie()
63+
node = node.children[index]
64+
node.is_end = True
65+
66+
def search(self, word: str) -> bool:
67+
"""
68+
Returns if the word is in the trie.
69+
"""
70+
node = self._search_prefix(word)
71+
return node is not None and node.is_end
72+
73+
def startsWith(self, prefix: str) -> bool:
74+
"""
75+
Returns if there is any word in the trie that starts with the given prefix.
76+
"""
77+
node = self._search_prefix(prefix)
78+
return node is not None
79+
80+
def _search_prefix(self, prefix: str):
81+
node = self
82+
for c in prefix:
83+
index = ord(c) - ord("a")
84+
if node.children[index] is None:
85+
return None
86+
node = node.children[index]
87+
return node
88+
89+
# Your Trie object will be instantiated and called as such:
90+
# obj = Trie()
91+
# obj.insert(word)
92+
# param_2 = obj.search(word)
93+
# param_3 = obj.startsWith(prefix)
4694
```
4795

4896
### **Java**
4997

5098
```java
51-
99+
class Trie {
100+
private Trie[] children;
101+
private boolean isEnd;
102+
103+
/** Initialize your data structure here. */
104+
public Trie() {
105+
children = new Trie[26];
106+
isEnd = false;
107+
}
108+
109+
/** Inserts a word into the trie. */
110+
public void insert(String word) {
111+
Trie node = this;
112+
for (int i = 0; i < word.length(); ++i) {
113+
char c = word.charAt(i);
114+
int index = c - 'a';
115+
if (node.children[index] == null) {
116+
node.children[index] = new Trie();
117+
}
118+
node = node.children[index];
119+
}
120+
node.isEnd = true;
121+
}
122+
123+
/** Returns if the word is in the trie. */
124+
public boolean search(String word) {
125+
Trie node = searchPrefix(word);
126+
return node != null && node.isEnd;
127+
}
128+
129+
/** Returns if there is any word in the trie that starts with the given prefix. */
130+
public boolean startsWith(String prefix) {
131+
Trie node = searchPrefix(prefix);
132+
return node != null;
133+
}
134+
135+
private Trie searchPrefix(String prefix) {
136+
Trie node = this;
137+
for (int i = 0; i < prefix.length(); ++i) {
138+
char c = prefix.charAt(i);
139+
int index = c - 'a';
140+
if (node.children[index] == null) {
141+
return null;
142+
}
143+
node = node.children[index];
144+
}
145+
return node;
146+
}
147+
}
148+
149+
/**
150+
* Your Trie object will be instantiated and called as such:
151+
* Trie obj = new Trie();
152+
* obj.insert(word);
153+
* boolean param_2 = obj.search(word);
154+
* boolean param_3 = obj.startsWith(prefix);
155+
*/
52156
```
53157

54158
### **...**
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,57 @@
11
class Trie {
2+
private Trie[] children;
3+
private boolean isEnd;
24

3-
class TrieNode {
4-
5-
private TrieNode[] links;
6-
7-
private final int R = 26;
8-
9-
private boolean isEnd;
10-
11-
public TrieNode() {
12-
links = new TrieNode[R];
13-
}
14-
15-
public boolean containsKey(char ch) {
16-
return links[ch -'a'] != null;
17-
}
18-
19-
public TrieNode get(char ch) {
20-
return links[ch -'a'];
21-
}
22-
23-
public void put(char ch, TrieNode node) {
24-
links[ch -'a'] = node;
25-
}
26-
27-
public void setEnd() {
28-
isEnd = true;
29-
}
30-
31-
public boolean isEnd() {
32-
return isEnd;
33-
}
34-
}
35-
36-
private TrieNode root;
37-
5+
/** Initialize your data structure here. */
386
public Trie() {
39-
root = new TrieNode();
7+
children = new Trie[26];
8+
isEnd = false;
409
}
41-
10+
11+
/** Inserts a word into the trie. */
4212
public void insert(String word) {
43-
TrieNode node = root;
44-
for (int i = 0; i < word.length(); i++) {
45-
char currentChar = word.charAt(i);
46-
if (!node.containsKey(currentChar)) {
47-
node.put(currentChar, new TrieNode());
13+
Trie node = this;
14+
for (int i = 0; i < word.length(); ++i) {
15+
char c = word.charAt(i);
16+
int index = c - 'a';
17+
if (node.children[index] == null) {
18+
node.children[index] = new Trie();
4819
}
49-
node = node.get(currentChar);
20+
node = node.children[index];
5021
}
51-
node.setEnd();
22+
node.isEnd = true;
23+
}
24+
25+
/** Returns if the word is in the trie. */
26+
public boolean search(String word) {
27+
Trie node = searchPrefix(word);
28+
return node != null && node.isEnd;
29+
}
30+
31+
/** Returns if there is any word in the trie that starts with the given prefix. */
32+
public boolean startsWith(String prefix) {
33+
Trie node = searchPrefix(prefix);
34+
return node != null;
5235
}
5336

54-
private TrieNode searchPrefix(String word) {
55-
TrieNode node = root;
56-
for (int i = 0; i < word.length(); i++) {
57-
char curLetter = word.charAt(i);
58-
if (node.containsKey(curLetter)) {
59-
node = node.get(curLetter);
60-
} else {
37+
private Trie searchPrefix(String prefix) {
38+
Trie node = this;
39+
for (int i = 0; i < prefix.length(); ++i) {
40+
char c = prefix.charAt(i);
41+
int index = c - 'a';
42+
if (node.children[index] == null) {
6143
return null;
6244
}
45+
node = node.children[index];
6346
}
6447
return node;
6548
}
66-
67-
public boolean search(String word) {
68-
TrieNode node = searchPrefix(word);
69-
return node != null && node.isEnd();
70-
}
71-
72-
public boolean startsWith(String prefix) {
73-
TrieNode node = searchPrefix(prefix);
74-
return node != null;
75-
}
76-
}
49+
}
50+
51+
/**
52+
* Your Trie object will be instantiated and called as such:
53+
* Trie obj = new Trie();
54+
* obj.insert(word);
55+
* boolean param_2 = obj.search(word);
56+
* boolean param_3 = obj.startsWith(prefix);
57+
*/

0 commit comments

Comments
 (0)