208. Implement Trie (Prefix Tree)
题目:
Implement a trie with insert, search, and startsWith methods.
链接: http://leetcode.com/problems/implement-trie-prefix-tree/
题解:
设计Trie。题目给了很多条件,所以大大简化了我们的思考时间。那么我们就构造一个经典的R-way Trie吧。首先要设计Trie节点,对R-way Trie的话我们使用一个R个元素的数组TrieNode[] next = new TrieNode[R],本题里R = 26,同时还有一个boolean变量isWord来确定当前节点是否为单词。 然后设计insert,search以及startWith。 具体设计思路完全参考了Sedgewick的课件,非常清楚。二刷要再多多练习计算复杂度以及Tenary-search Trie和Suffix Tree/Suffix Trie的东西,也要看一看Eric Demaine的MIT视频里String那一课。
Time Complexity - O(n) for each insert,search,startWith, Space Complexity - O(26n), n为word的平均长度。假如m个单词的话 Space Complexity是 - O(m * 26n)
class TrieNode {
// Initialize your data structure here.
public boolean isWord;
public TrieNode[] next;
private final int R = 26; // R-way Trie
public TrieNode() {
next = new TrieNode[R];
}
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// Inserts a word into the trie.
public void insert(String word) {
if(word == null || word.length() == 0)
return;
TrieNode node = root;
int d = 0; // depth/distance
while(d < word.length()) {
char c = word.charAt(d);
if(node.next[c - 'a'] == null)
node.next[c - 'a'] = new TrieNode();
node = node.next[c - 'a'];
d++;
}
node.isWord = true;
}
// Returns if the word is in the trie.
public boolean search(String word) {
if(word == null || word.length() == 0)
return false;
TrieNode node = root;
int d = 0;
while(d < word.length()) {
char c = word.charAt(d);
if(node.next[c - 'a'] == null) // did not find char within word
return false;
node = node.next[c - 'a'];
d++;
}
return node.isWord;
}
// Returns if there is any word in the trie
// that starts with the given prefix.
public boolean startsWith(String prefix) {
if(prefix == null || prefix.length() == 0)
return false;
TrieNode node = root;
int d = 0;
while(d < prefix.length()) {
char c = prefix.charAt(d);
if(node.next[c - 'a'] == null) // did not find char within prefix
return false;
node = node.next[c - 'a'];
d++;
}
return true;
}
}
// Your Trie object will be instantiated and called as such:
// Trie trie = new Trie();
// trie.insert("somestring");
// trie.search("key");
二刷:
还是写得少,并不熟悉,只有个大概印象,可能要刷三到四遍才会深刻一点。
对于TrieNode的设计:
- 一般的R-way Trie就是每一个节点TrieNode有R个子节点,我们可以用一个数组来表示子节点。
- 数组的大小要根据题意来定,比如这道题说明了alphabet = 'a' 到 'z', 那么我们的R就等于26,做一个26-way Trie就可以了。
- 要有一个boolean变量isWord来表明这个节点是否是单词的结尾。
- 在Trie里面的首先要初始化一个root节点。 TrieNode root = new TrieNode(); 这个节点我们不保存任何字母。
对于insert
- 首先处理一下边界条件
- 设置一个变量d = 0代表深度depth
- 设置一个TrieNode node = root,这里算是获取一个root的reference
- 当d < word.length()时,我们根据word.charAt(d) - 'a'来算得 word的第一个字母应该保存的位置index
- 查看word.next[index],假如其为空,那么我们要创建一个新的TrieNode。不为空的时候不用管,直接运行6。
- 更新node = node.next[index], d++, 继续处理word中的下一个字母
- 全部遍历完毕以后,设置node.isWord = true,表明root到这个node的路径是一个单词。
对于search和startWith
- 1 ~ 4步跟insert都一样
- 查看woird.next[index],假如其为空直接返回false
- 更新node = node.next[index], d++,继续查找word中的下一个字母
- 最后一步,对于Search来说,我们要根据node.isWord来决定是否查找成功。 对于startWith来说我们直接返回true。
Java:
Time Complexity - O(n) for each insert,search,startWith, Space Complexity - O(26n), n为word的平均长度。假如m个单词的话, Space Complexity就是是 - O(m * 26n)
class TrieNode {
// Initialize your data structure here.
TrieNode[] next;
boolean isWord;
int R = 26; // radix 'a' - 'z'
public TrieNode() {
this.next = new TrieNode[R];
}
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// Inserts a word into the trie.
public void insert(String word) {
if (word == null || word.length() == 0) return;
TrieNode node = root;
int d = 0;
while (d < word.length()) {
int index = word.charAt(d) - 'a';
if (node.next[index] == null) node.next[index] = new TrieNode();
node = node.next[index];
d++;
}
node.isWord = true;
}
// Returns if the word is in the trie.
public boolean search(String word) {
if (word == null || word.length() == 0) return false;
TrieNode node = root;
int d = 0;
while (d < word.length()) {
int index = word.charAt(d) - 'a';
if (node.next[index] == null) return false;
node = node.next[index];
d++;
}
return node.isWord;
}
// Returns if there is any word in the trie
// that starts with the given prefix.
public boolean startsWith(String prefix) {
if (prefix == null || prefix.length() == 0) return false;
TrieNode node = root;
int d = 0;
while (d < prefix.length()) {
int index = prefix.charAt(d) - 'a';
if (node.next[index] == null) return false;
node = node.next[index];
d++;
}
return true;
}
}
// Your Trie object will be instantiated and called as such:
// Trie trie = new Trie();
// trie.insert("somestring");
// trie.search("key");
Reference:
http://algs4.cs.princeton.edu/52trie/
https://en.wikipedia.org/wiki/Trie
https://en.wikipedia.org/wiki/Suffix_tree
208. Implement Trie (Prefix Tree)的更多相关文章
- 字典树(查找树) leetcode 208. Implement Trie (Prefix Tree) 、211. Add and Search Word - Data structure design
字典树(查找树) 26个分支作用:检测字符串是否在这个字典里面插入.查找 字典树与哈希表的对比:时间复杂度:以字符来看:O(N).O(N) 以字符串来看:O(1).O(1)空间复杂度:字典树远远小于哈 ...
- 【LeetCode】208. Implement Trie (Prefix Tree)
Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Note:You ...
- [LeetCode] 208. Implement Trie (Prefix Tree) ☆☆☆
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- 【刷题-LeetCode】208. Implement Trie (Prefix Tree)
Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Example: ...
- 【LeetCode】208. Implement Trie (Prefix Tree) 实现 Trie (前缀树)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:Leetcode, 力扣,Trie, 前缀树,字典树,20 ...
- 【leetcode】208. Implement Trie (Prefix Tree 字典树)
A trie (pronounced as "try") or prefix tree is a tree data structure used to efficiently s ...
- [LeetCode] 208. Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie. ...
- Java for LeetCode 208 Implement Trie (Prefix Tree)
Implement a trie with insert, search, and startsWith methods. Note: You may assume that all inputs a ...
- 208. Implement Trie (Prefix Tree) -- 键树
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
随机推荐
- MyEclipse导入ant项目——Java编程思想
北门煎饼东门串儿: <JAVA编程思想(Think in Java)>一书中提供了大量源代码,可是项目是用ant构建的.对于用惯了eclipse,netbeans等IDE的同学们可能有些手 ...
- 哆啦A梦连连看游戏源码完整版
这个源码是哆啦A梦连连看游戏源码完整版,也是安卓教程网android.662p.com分享过来的,哆啦A梦大家一定再熟悉不过了,这次登场的角色你能认出全部吗?赶紧把相同的小图标全部消除吧,一起体验下! ...
- winForm 中子窗体关闭但不释放对象,方便下次继续打开
方法一: 修改子窗体中自动生成的Dispose方法(在Form.Designer.cs文件中) /// <summary> /// Clean up any resources being ...
- 【Qt】Qt Creator键盘快捷键速查
附录 Qt Creator键盘快捷键速查 一般操作的键盘快捷键 操作 快捷键 操作 快捷键 打开文件或项目 Ctrl+O 新建文件或项目 Ctrl+N 在外部编辑器中打开 Alt+V,Alt+I 选择 ...
- 页面有什么隐藏bug:字体,图片
字体: 一行(太长)-display:inline-block,text-overflow: ellipsis;max-width:xxpx 多行(太高,太矮)-设置max-height,min-he ...
- wampsever在win10中安装扩展掉坑
1.必须要退出wampserver 2.php pecl + 3.wampserver 64 3.0.6
- http中的KeepAlive
为什么要使用KeepAlive? 终极的原因就是需要加快客户端和服务端的访问请求速度.KeepAlive就是浏览器和服务端之间保持长连接,这个连接是可以复用的.当客户端发送一次请求,收到相应以后,第二 ...
- Ubuntu 14.04的SWAP 为0
[@@@@@@]# free total used free shared buffers cached Mem: 1024976 248992 775984 0 16820 73128 -/+ bu ...
- MVC-HtmlHelper扩展
1.添加对System.Web.Mvc的引用 2.添加一个静态类,里面的扩展方法也必须是静态的 //HtmlHelper扩展类 //添加对System.Web.Mvc的引用 //命名空间:System ...
- 理解UIEdgeInsets
供参考 iOS 的控件,只看到 UIButton 可以设置 Padding/Insets,即按钮上文字或图片与按钮边界的间隙. CSS 上叫做 Padding,在 iOS 中叫做 Insets,UIB ...