10.1 前缀树基础
...大约 2 分钟
In computer science, a trie (/ˈtriː/, /ˈtraɪ/), also called digital tree or prefix tree, is a type of k-ary search tree, a tree data structure used for locating specific keys from within a set. These keys are most often strings, with links between nodes defined not by the entire key, but by individual characters.
前缀树, 又称字典树, 用树状结构来表示字典中的所有单词; 除根节点外, 每个节点表示一个字母, 单词则由路径表示.
10.1.1 实现前缀树
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
请你实现 Trie 类:
Trie()
初始化前缀树对象。void insert(String word)
向前缀树中插入字符串word
。boolean search(String word)
如果字符串word
在前缀树中,返回true
(即,在检索之前已经插入);否则,返回false
。boolean startsWith(String prefix)
如果之前已经插入的字符串word
的前缀之一为prefix
,返回true
;否则,返回false
。示例:
输入 inputs = ["Trie", "insert", "search", "search", "startsWith", "insert", "search"] inputs = [[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]] 输出 [null, null, true, false, true, null, true] 解释 Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // 返回 True trie.search("app"); // 返回 False trie.startsWith("app"); // 返回 True trie.insert("app"); trie.search("app"); // 返回 True
提示:
1 <= word.length, prefix.length <= 2000
word
和prefix
仅由小写英文字母组成insert
、search
和startsWith
调用次数 总计 不超过3 * 10^4
次
10.1.1.1 分析
因为单词仅由26个字母组成, 那么每个节点子子节点数量最大为26, 可以用数组表示[26]*Trie
. 还需要一个变量isWord
表示是否是完整单词.
type Trie struct {
children [26]*Trie
isWord bool
}
search
查找操作从根节点出发, 寻找每个字母是否在前缀树路径中存在:
- 若有字母不在路径中, 返回false
- 若匹配到完整路径, 结果取决于最后一个节点的
isWord
, 表示完整单词是否存在.
startWith
和search
类似, 但是匹配到最后一个字母时, 无需判断isWord
.
10.1.1.2 题解
单词长度为n, insert
, search
,startWith
时间复杂度均为 O(n)
type Trie struct {
children [26]*Trie
isWord bool
}
func Constructor() Trie {
return Trie{}
}
func (t *Trie) Insert(word string) {
cur := t
for _, c := range word {
c -= 'a'
if cur.children[c] == nil {
cur.children[c] = &Trie{}
}
cur = cur.children[c]
}
cur.isWord = true
}
func (t *Trie) Search(word string) bool {
cur := t
for _, c := range word {
c -= 'a'
if cur.children[c] == nil {
return false
}
cur = cur.children[c]
}
return cur.isWord
}
func (t *Trie) StartsWith(prefix string) bool {
cur := t
for _, c := range prefix {
c -= 'a'
if cur.children[c] == nil {
return false
}
cur = cur.children[c]
}
return true
}
Reference
- 剑指Offer(专项突破版)
- Trie wiki
Powered by Waline v2.15.2