LeetCode 208. Implement Trie (Prefix Tree) (實現Trie樹)
阿新 • • 發佈:2018-12-03
原題
Implement a trie with insert
, search
, and startsWith
methods.
Example:
Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // returns true trie.search("app"); // returns false trie.startsWith("app"); // returns true trie.insert("app"); trie.search("app"); // returns true
Note:
- You may assume that all inputs are consist of lowercase letters
a-z
. - All inputs are guaranteed to be non-empty strings.
Reference Answer
補充知識
實現字典樹。字典樹:
上圖是一棵Trie樹,表示了關鍵字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。從上圖可以歸納出Trie樹的基本性質:
根節點不包含字元,除根節點外的每一個子節點都包含一個字元。
從根節點到某一個節點,路徑上經過的字元連線起來,為該節點對應的字串。
每個節點的所有子節點包含的字元互不相同。
通常在實現的時候,會在節點結構中設定一個標誌,用來標記該結點處是否構成一個單詞(關鍵字)。
可以看出,Trie樹的關鍵字一般都是字串,而且Trie樹把每個關鍵字儲存在一條路徑上,而不是一個結點中。另外,兩個有公共字首的關鍵字,在Trie樹中字首部分的路徑相同,所以Trie樹又叫做字首樹(Prefix Tree)。
思路分析
每個節點的子孩子都是一個字典,根據字典查詢下一個位置的節點,就像字典一樣。同事用isword儲存當前是不是一個詞(也可能是路徑中的點)。
這道題自己開始想簡單了,想著只用list進行操作就好了,沒想到使用Prefix Tree結構,結果發現,時間複雜度超出要求,必須還是要回到Prefix Tree結構
My Code
時間複雜度超過要求,失敗!
class Trie:
def __init__(self):
"""
Initialize your data structure here.
"""
self.res = []
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: void
"""
self.res.insert(0, word)
def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
for x in self.res:
if x == word:
return True
return False
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
# if not prefix:
# return True
if not self.res:
return False
for count in self.res:
base = count
if base[0] != prefix[0]:
continue
len_base = len(base)
len_target = len(prefix)
if len_target > len_base:
continue
if prefix == base[:len_target]:
return True
return False
# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)
Reference Code (Prefix Tree)
class Node(object):
def __init__(self):
self.children = collections.defaultdict(Node)
self.isword = False
class Trie(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.root = Node()
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: void
"""
current = self.root
for w in word:
current = current.children[w]
current.isword = True
def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
current = self.root
for w in word:
current = current.children.get(w)
if current == None:
return False
return current.isword
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
current = self.root
for w in prefix:
current = current.children.get(w)
if current == None:
return False
return True
# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)
Note:
- 注意Python結構體的實現及使用方式;
collections.defaultdict(Node)
的使用方式,其中collections.defaultdict()
中可以為int
,為str
及list
,也可以自定義結構型別,如本題中的Node
;
參考文獻
[1] https://blog.csdn.net/fuxuemingzhu/article/details/79388432