Skip to content

Commit cb2a392

Browse files
author
weiy
committed
Trie
1 parent 0ddcc33 commit cb2a392

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

Tree/Trie.py

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
"""
2+
前缀树又叫字典树,该树会覆盖多个相同的字符以形成空间上的优势。
3+
4+
如:
5+
rat 与 rain
6+
r
7+
a
8+
t i
9+
n
10+
最终会形成这样的树。
11+
12+
字典树有多种实现方式,下面直接用了列表(数组)来实现。
13+
测试用例:
14+
https://leetcode.com/problems/implement-trie-prefix-tree/description/
15+
16+
使用Python 中的字典可以直接形成这种树,所以弃用这种方式,用类的思路实现了一下。
17+
18+
"""
19+
20+
class TrieNode(object):
21+
# __slots__ 考虑到TrieNode会大量创建,使用 __slot__来减少内存的占用。
22+
# 在测试的15个例子中:
23+
# 使用 __slots__会加快创建,平均的耗时为290ms-320ms。
24+
# 而不使用则在 340ms-360ms之间。
25+
# 创建的越多效果越明显。
26+
# 当然,使用字典而不是类的方式会更加更加更加高效。
27+
__slots__ = {'value', 'nextNodes', 'breakable'}
28+
29+
def __init__(self, value, nextNode=None):
30+
self.value = value
31+
if nextNode:
32+
self.nextNodes = [nextNode]
33+
else:
34+
self.nextNodes = []
35+
self.breakable = False
36+
37+
def addNext(self, nextNode):
38+
self.nextNodes.append(nextNode)
39+
40+
def setBreakable(self, enable):
41+
self.breakable = enable
42+
43+
def __eq__(self, other):
44+
return self.value == other
45+
46+
47+
48+
class Trie(object):
49+
50+
def __init__(self):
51+
"""
52+
Initialize your data structure here.
53+
"""
54+
self.root = []
55+
56+
57+
def insert(self, word):
58+
"""
59+
Inserts a word into the trie.
60+
:type word: str
61+
:rtype: void
62+
"""
63+
self.makeATrieNodes(word)
64+
65+
def search(self, word):
66+
"""
67+
Returns if the word is in the trie.
68+
:type word: str
69+
:rtype: bool
70+
"""
71+
for i in self.root:
72+
if i == word[0]:
73+
74+
return self._search(i, word[1:])
75+
return False
76+
77+
def _search(self, root, word):
78+
if not word:
79+
if root.breakable:
80+
return True
81+
return False
82+
if not root.nextNodes:
83+
return False
84+
85+
for i in root.nextNodes:
86+
if i == word[0]:
87+
return self._search(i, word[1:])
88+
89+
return False
90+
91+
def startsWith(self, prefix):
92+
"""
93+
Returns if there is any word in the trie that starts with the given prefix.
94+
:type prefix: str
95+
:rtype: bool
96+
"""
97+
for i in self.root:
98+
if i == prefix[0]:
99+
return self._startWith(i, prefix[1:])
100+
return False
101+
102+
def _startWith(self, root, prefix):
103+
if not prefix:
104+
return True
105+
106+
if not root.nextNodes:
107+
return False
108+
109+
for i in root.nextNodes:
110+
if i == prefix[0]:
111+
return self._startWith(i, prefix[1:])
112+
113+
return False
114+
115+
def makeATrieNodes(self, word):
116+
for j in self.root:
117+
if word[0] == j:
118+
rootWord = j
119+
break
120+
else:
121+
122+
rootWord = TrieNode(word[0])
123+
self.root.append(rootWord)
124+
for i in word[1:]:
125+
nextNode = TrieNode(i)
126+
rootWord.addNext(nextNode)
127+
rootWord = nextNode
128+
rootWord.setBreakable(True)
129+
return
130+
131+
# has the letter.
132+
word = word[1:]
133+
while 1:
134+
if not word:
135+
rootWord.setBreakable(True)
136+
break
137+
138+
for i in rootWord.nextNodes:
139+
if i == word[0]:
140+
rootWord = i
141+
word = word[1:]
142+
break
143+
else:
144+
for i in word:
145+
nextNode = TrieNode(i)
146+
rootWord.addNext(nextNode)
147+
rootWord = nextNode
148+
rootWord.setBreakable(True)
149+
break

0 commit comments

Comments
 (0)