实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
示例:
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
说明:
你可以假设所有的输入都是由小写字母 a-z 构成的。
保证所有输入均为非空字符串。
let aAsciiValue = Int(Character("a").asciiValue ?? 97)
class Trie {
var child:[Trie?] = [Trie?](repeating: nil, count: 26)
let R = 26
var isEnd = false
init() {}
func insert(_ word: String) {
var cur: Trie = self
for char in word {
guard let asciValue = char.asciiValue else {return}
let index = Int(asciValue) - aAsciiValue
var nextNode = cur.child[index]
if nextNode == nil { // 如果为空,创建一个,并插入到对应的位置
nextNode = Trie()
cur.child[index] = nextNode
}
// 最后切换到nextNode里面进行设置下一个字符
cur = nextNode!
}
cur.isEnd = true
}
// search a prefix or whole key in trie and
// returns the node where search ends
// 查找键
func search(_ word: String) -> Bool {
var cur: Trie = self
for char in word {
guard let asciV = char.asciiValue else {return false}
let index = Int(asciV) - aAsciiValue
guard let nextNode = cur.child[index] else{return false}
cur = nextNode // 如果找不到,说明没有这个单词
}
// 到这里,说明已经遍历完成了,需要看是不是最后一个的,例如 and 里面包含了 an,但不包含这个单词
return cur.isEnd
}
func startsWith(_ word: String) -> Bool {
var cur: Trie = self
for char in word {
guard let asciiValue = char.asciiValue else {return false}
let index = Int(asciiValue) - aAsciiValue
guard let nextNode = cur.child[index] else {return false}
cur = nextNode
}
return true
}
}