题目:

Implement a trie with insertsearch, 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的设计:

  1. 一般的R-way Trie就是每一个节点TrieNode有R个子节点,我们可以用一个数组来表示子节点。
  2. 数组的大小要根据题意来定,比如这道题说明了alphabet = 'a' 到 'z', 那么我们的R就等于26,做一个26-way Trie就可以了。
  3. 要有一个boolean变量isWord来表明这个节点是否是单词的结尾。
  4. 在Trie里面的首先要初始化一个root节点。  TrieNode root = new TrieNode(); 这个节点我们不保存任何字母。

对于insert

  1. 首先处理一下边界条件
  2. 设置一个变量d = 0代表深度depth
  3. 设置一个TrieNode node = root,这里算是获取一个root的reference
  4. 当d < word.length()时,我们根据word.charAt(d) - 'a'来算得 word的第一个字母应该保存的位置index
  5. 查看word.next[index],假如其为空,那么我们要创建一个新的TrieNode。不为空的时候不用管,直接运行6。
  6. 更新node = node.next[index], d++, 继续处理word中的下一个字母
  7. 全部遍历完毕以后,设置node.isWord = true,表明root到这个node的路径是一个单词。

对于search和startWith

  1. 1 ~ 4步跟insert都一样
  2. 查看woird.next[index],假如其为空直接返回false
  3. 更新node = node.next[index], d++,继续查找word中的下一个字母
  4. 最后一步,对于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)的更多相关文章

  1. 字典树(查找树) leetcode 208. Implement Trie (Prefix Tree) 、211. Add and Search Word - Data structure design

    字典树(查找树) 26个分支作用:检测字符串是否在这个字典里面插入.查找 字典树与哈希表的对比:时间复杂度:以字符来看:O(N).O(N) 以字符串来看:O(1).O(1)空间复杂度:字典树远远小于哈 ...

  2. 【LeetCode】208. Implement Trie (Prefix Tree)

    Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Note:You ...

  3. [LeetCode] 208. Implement Trie (Prefix Tree) ☆☆☆

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  4. 【刷题-LeetCode】208. Implement Trie (Prefix Tree)

    Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Example: ...

  5. 【LeetCode】208. Implement Trie (Prefix Tree) 实现 Trie (前缀树)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:Leetcode, 力扣,Trie, 前缀树,字典树,20 ...

  6. 【leetcode】208. Implement Trie (Prefix Tree 字典树)

    A trie (pronounced as "try") or prefix tree is a tree data structure used to efficiently s ...

  7. [LeetCode] 208. Implement Trie (Prefix Tree) 实现字典树(前缀树)

    Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie. ...

  8. 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 ...

  9. 208. Implement Trie (Prefix Tree) -- 键树

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

随机推荐

  1. Oracle常见的问题

    1.oracle 中文问号乱码解决方法: 在系统变量里面添加变量名:NLS_LANG 变量值:  SIMPLIFIED CHINESE_CHINA.ZHS16GBK 2.查询oracle 里的主键 S ...

  2. 暑假集训(4)第八弹——— 组合(hdu1524)

    题意概括:你已经赢得两局,最后一局是N个棋子往后移动,最后一个无法移动的玩家失败. 题目分析:有向无环图sg值游戏,尼姆游戏的抽象表达.得到每个棋子的sg值之后,把他们异或起来,考察异或值是否为0. ...

  3. Linux ---> 简单socket

    #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> ...

  4. 加密解密以及CA签证

    在当今互联网时代,数据越来越来重要.那么如何加密?解密?以及通过什么方式来认证了?? 接下来,我就会和大家谈谈加密,解密以及CA签证的实现. 首先大家的知道一些加密,解密的基本常识: 互联网上中间人一 ...

  5. JS传参出现乱码(转载)

    问题说明:在进行网站开发时,将表单的提交功能交给JS来传递,但是在传递中文的过程中出现类似于繁体字的乱码. 解决方案:为了解决这个问题,首先从底层的C#代码审查,重新设置页面传值进行模拟,但是几经测试 ...

  6. js数字格式化-四舍五入精简版

    搜索网上的,数字格式化过余复杂,自己想了个简单方法,欢迎吐槽. 简化说明: '123333' => 12.3万 parseInt('123333') 字符串转整型 parseInt('12333 ...

  7. 【Delphi】窗体阴影

    procedure TForm1.FormCreate(Sender: TObject); begin SetClassLong(Handle, GCL_STYLE, GetClassLong(Han ...

  8. javascript实现URL不缓存的方法

    <script> document.write("<s"+"cript type='text/javascript' src='/js/test.js? ...

  9. cwm-recovery自动生成工具

    android发展迅速,刷机已经成了一种习惯,cwm-recovery是必不可少的工具,下面我把自己用的自动生成cwm-recovery的工具发布出来,供友友们交流和学习,欢迎拍砖 已经公开发布在gi ...

  10. hdu 4641 K-string SAM的O(n^2)算法 以及 SAM+并查集优化

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4641 题意:有一个长度为n(n < 5e4)的字符串,Q(Q<=2e5)次操作:操作分为:在末 ...