实现一个 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构成的。 - 保证所有输入均为非空字符串。
解题思路:
26叉树。使用26叉树储存英文单词,仅有小写字母,因此只有26个分支。主要的技术在于构造26叉树的结点。
struct TreeNode26 {
char val;
TreeNode26* next[26];
bool isLast = false;
TreeNode26(char v) {
val = v;
for (int i = 1; i <= 26; i++) {
next[i - 1] = NULL;
}
}
bool hasChild26() {
for (int i = 1; i <= 26; i++) {
if (next[i - 1]) return true;
}
return false;
}
};
TreeNode26包含当前结点的字符val,isLast用于保存当前结点是否是单词末尾,以便于访问前缀。*next[26]是26个分支,代表下一个字符的所有可能性,数组下标0-25分别表示a-z26个英文单词的位置。
1. 插入单词。
从根结点开始,根结点一般不用。依次将字符串中的每一个字符放入26叉树中,直到遍历所有字符。将最后一个字符所在的结点的isLast属性设置为true,表明这个结点是一个单词的末尾。从这个结点开始一直查找他的父亲便可以得到整个单词(本题不需要)。
2. 查找单词
遍历整个单词,从根节点向下,依次查找他的孩子中是否有当前访问的字符。一旦遇到查找失败说明查找的单词不存在。如果能够查找到所有字母,并且最后一个结点是某一个单词的末尾(isLast==true),说明查找成功,否者它只是一个单词的前缀。
3. 查找前缀
遍历整个单词,从根节点向下,依次查找他的孩子中是否有当前访问的字符。一旦遇到查找失败说明查找的单词不存在。如果能够查找到所有字母,说明必然有这个前缀。
经测试,当前时刻, 小于56ms的代码运行时间均在56ms附近。
|
struct TreeNode26 { }; |