LeetCode 208. Implement Trie (Prefix Tree)

Implement a trie with insertsearch, and startsWith methods.

Note:
You may assume that all inputs are consist of lowercase letters a-z.

这道题让我们实现一个重要但又有些复杂的数据结构-字典树, 又称前缀树或单词查找树,详细介绍可以参见网友董的博客,例如,一个保存了8个键的trie结构,"A", "to", "tea", "ted", "ten", "i", "in", and "inn".如下图所示:

字典树主要有如下三点性质:

1. 根节点不包含字符,除根节点意外每个节点只包含一个字符。

2. 从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。

3. 每个节点的所有子节点包含的字符串不相同。

字母树的插入(Insert)、删除( Delete)和查找(Find)都非常简单,用一个一重循环即可,即第i 次循环找到前i 个字母所对应的子树,然后进行相应的操作。实现这棵字母树,我们用最常见的数组保存(静态开辟内存)即可,当然也可以开动态的指针类型(动态开辟内存)。至于结点对儿子的指向,一般有三种方法:

1、对每个结点开一个字母集大小的数组,对应的下标是儿子所表示的字母,内容则是这个儿子对应在大数组上的位置,即标号;

2、对每个结点挂一个链表,按一定顺序记录每个儿子是谁;

3、使用左儿子右兄弟表示法记录这棵树。

两种方法,各有特点。第一种易实现,但实际的空间要求较大;第二种,空间要求最小,但相对费时且不易写。

1.我们先来看第一种实现方法,这种方法实现起来简单直观,字母的字典树每个节点要定义一个大小为26的子节点指针数组,然后用一个标志符用来记录到当前位置为止是否为一个词,初始化的时候讲26个子节点都赋为空。那么insert操作只需要对于要插入的字符串的每一个字符算出其的位置,然后找是否存在这个子节点,若不存在则新建一个,然后再查找下一个。查找词和找前缀操作跟insert操作都很类似,不同点在于若不存在子节点,则返回false。查找次最后还要看标识位,而找前缀直接返回true即可

 1 class TrieNode {
 2     public char val;
 3     public boolean isWord;
 4     public TrieNode[] children = new TrieNode[26];
 5     public TrieNode() {}
 6     TrieNode(char c){
 7         TrieNode node = new TrieNode();
 8         node.val = c;
 9     }
10 }
11
12 public class Trie {
13     private TrieNode root;
14     public Trie() {
15         root = new TrieNode();
16         root.val = ‘ ‘;
17     }
18
19     public void insert(String word) {
20         TrieNode ws = root;
21         for(int i = 0; i < word.length(); i++){
22             char c = word.charAt(i);
23             if(ws.children[c - ‘a‘] == null){
24                 ws.children[c - ‘a‘] = new TrieNode(c);
25             }
26             ws = ws.children[c - ‘a‘];
27         }
28         ws.isWord = true;
29     }
30
31     public boolean search(String word) {
32         TrieNode ws = root;
33         for(int i = 0; i < word.length(); i++){
34             char c = word.charAt(i);
35             if(ws.children[c - ‘a‘] == null) return false;
36             ws = ws.children[c - ‘a‘];
37         }
38         return ws.isWord;
39     }
40
41     public boolean startsWith(String prefix) {
42         TrieNode ws = root;
43         for(int i = 0; i < prefix.length(); i++){
44             char c = prefix.charAt(i);
45             if(ws.children[c - ‘a‘] == null) return false;
46             ws = ws.children[c - ‘a‘];
47         }
48         return true;
49     }
50 }

2.

  1 class Trie {
  2     private String letter;
  3     private List<Trie> children;
  4     private boolean end;
  5     /** Initialize your data structure here. */
  6     public Trie() {
  7         this.letter = "";
  8         this.children = new ArrayList<Trie>();
  9         boolean end = false;
 10     }
 11
 12     public Trie(String letter) {
 13         this.letter = letter;
 14         this.children = new ArrayList<Trie>();
 15         this.end = false;
 16     }
 17
 18     /** Inserts a word into the trie. */
 19     public void insert(String word) {
 20         insertHelper(this, word, 0);
 21     }
 22
 23     /** Returns if the word is in the trie. */
 24     public boolean search(String word) {
 25         boolean result = true;
 26         result = result && searchHelper(this, word, 0);
 27         return result;
 28     }
 29
 30     /** Returns if there is any word in the trie that starts with the given prefix. */
 31     public boolean startsWith(String prefix) {
 32         if (prefix.length() == 0)
 33             return true;
 34         boolean result = false;
 35         for(Trie trie: children){
 36             if (trie.letter.equals(prefix.charAt(0) + "")){
 37                 result = true && startsWithHelper(trie, prefix, 1);
 38                 if(result == false)
 39                     return false;
 40             }
 41         }
 42         return result;
 43     }
 44
 45     private boolean startsWithHelper(Trie trie, String prefix, int pos){
 46         if(pos == prefix.length())
 47             return true;
 48         boolean result = false;
 49         for(Trie child: trie.children){
 50             if(child.letter.equals(prefix.charAt(pos) + "")){
 51                 result = true && startsWithHelper(child, prefix, pos +1);
 52                 if(result == false)
 53                     return false;
 54             }
 55         }
 56         return result;
 57     }
 58
 59     private void insertHelper(Trie trie, String word, int pos){
 60         boolean has = false;
 61         if(pos == word.length())
 62             return;
 63         int len = trie.children.size();
 64         for(int i=0; i < len; i++){
 65             Trie child = trie.children.get(i);
 66             if(child.letter.equals(word.charAt(pos) + "")){
 67                 has = true;
 68                 if(pos == word.length()-1){
 69                     if(child.end == false){
 70                         child.end = true;
 71                     }
 72                 }
 73                 insertHelper(child, word, pos+1);
 74             }
 75         }
 76         if(!has)
 77             create(trie,word,pos);
 78     }
 79
 80     private void create(Trie parent, String word, int pos){
 81         if(pos == word.length())
 82             return;
 83         Trie child = new Trie(word.charAt(pos) + "");
 84         if(pos == word.length() -1)
 85             child.end = true;
 86         parent.children.add(child);
 87         create(child, word, pos+1);
 88     }
 89
 90     private boolean searchHelper(Trie trie, String word, int pos){
 91         if(pos == word.length() && trie.children.size() == 0)
 92             return true;
 93         else if(pos == word.length())
 94             return false;
 95         boolean result = false;
 96         for(Trie child: trie.children){
 97             if(child.letter.equals(word.charAt(pos) + "")){
 98                 if(pos == word.length() -1){
 99                     if(child.end == true)
100                         return true;
101                     else
102                         return false;
103                 }
104                 result = true && searchHelper(child, word, pos +1);
105                 if(result == false)
106                     return false;
107             }
109         }
110         return result;
111     }
112 }
时间: 2024-11-13 08:37:04

LeetCode 208. Implement Trie (Prefix Tree)的相关文章

[LeetCode] 208. Implement Trie (Prefix Tree) Java

题目: Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs are consist of lowercase letters a-z. 题意及分析:实现一个字典树或者叫前缀树的插入.删除和startsWith判断.这里定义一个trieNode类作为字典树的节点类.然后有一个chilrden数组保存子节点,一个isWord变量来判断从根节点到该节点是否是一

Java for LeetCode 208 Implement Trie (Prefix Tree)

Implement a trie with insert, search, and startsWith methods. Note: You may assume that all inputs are consist of lowercase letters a-z. 解题思路: 参考百度百科:Trie树 已经给出了详细的代码: JAVA实现如下: class TrieNode { // Initialize your data structure here. int num;// 有多少单

[LeetCode][JavaScript]Implement Trie (Prefix Tree)

Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. https://leetcode.com/problems/implement-trie-prefix-tree/ 实现字典树,每个节点至多有26个子孙,代表26个字母. 每个节点都有三个属性,key, isWord以及字典(哈希表,提高访问速度,也可以用数组),因为JS可以扩展实例化的对象,直接用下标访问对象,不需

[leetcode trie]208. Implement Trie (Prefix Tree)

实现一个字典树 1 class Trie(object): 2 3 def __init__(self): 4 self.root = TrieNode() 5 6 def insert(self, word): 7 cur = self.root 8 for i in word: 9 cur = cur.children[i] 10 cur.is_word = True 11 12 13 def search(self, word): 14 cur = self.root 15 for i i

208. Implement Trie (Prefix Tree)

题目: Implement a trie with insert, search, and startsWith methods. 链接: http://leetcode.com/problems/implement-trie-prefix-tree/ 7/14/201760%,照着课件代码改写的. 将val cast成boolean,注意第21行需要设为false.以下代码可以不需要看,第一版虽然通过了,但是具体内容并不了解. 1 public class Trie { 2 private s

[leedcode 208] Implement Trie (Prefix Tree)

Trie树又被称为字典树.前缀树,是一种用于快速检索的多叉树.Tried树可以利用字符串的公共前缀来节省存储空间. 但如果系统存在大量没有公共前缀的字符串,相应的Trie树将非常消耗内存.(下图为Wiki上的Trie树示意图, https://en.wikipedia.org/wiki/Trie) 子节点用hashMap表示 isWord标记从根节点到该节点是否表示一个单词,还是另一单词的前缀. Implement a trie with insert, search, and startsWi

[email&#160;protected] [208] Implement Trie (Prefix Tree)

Trie 树模板 https://leetcode.com/problems/implement-trie-prefix-tree/ class TrieNode { public: char var; bool isWord; TrieNode *next[26]; TrieNode() { var = 0; this->isWord = false; for(auto &c : next) c = NULL; } TrieNode(char c) { var = c; this->

208. Implement Trie (Prefix Tree)字典树

Implement a trie with insert, search, and startsWith methods. Note: You may assume that all inputs are consist of lowercase letters a-z. 在Trie树中主要有3个操作,插入.查找和删除.一般情况下Trie树中很少存在删除单独某个结点的情况,因此只考虑删除整棵树. 1.插入 假设存在字符串str,Trie树的根结点为root.i=0,p=root. 1)取str[

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

Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs are consist of lowercase letters a-z. class TrieNode { public: // Initialize your data structure here. bool isWord; unordered_map<char, TrieNode*> alph