• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
neverlandly
博客园    首页    新随笔    联系   管理    订阅  订阅

Leetcode: Implement Trie (Prefix Tree) && Summary: Trie

Implement a trie with insert, search, and startsWith methods.

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

参考百度百科:Trie树

a trie, also called digital tree and sometimes radix tree or prefix tree (as they can be searched by prefixes)

The time complexity to insert and to search is O(m), where m is the length of the string.

标准Trie树的应用和优缺点

     (1) 全字匹配:确定待查字串是否与集合的一个单词完全匹配。如上代码fullMatch()。

     (2) 前缀匹配:查找集合中与以s为前缀的所有串。

 

     注意:Trie树的结构并不适合用来查找子串。这一点和前面提到的PAT Tree以及后面专门要提到的Suffix Tree的作用有很大不同。

 

      优点: 查找效率比与集合中的每一个字符串做匹配的效率要高很多。在o(m)时间内搜索一个长度为m的字符串s是否在字典里。Predictable O(k) lookup time where k is the size of the key

      缺点:标准Trie的空间利用率不高,可能存在大量结点中只有一个子结点,这样的结点绝对是一种浪费。正是这个原因,才迅速推动了下面所讲的压缩trie的开发。

什么时候用Trie?

It all depends on what problem you're trying to solve. If all you need to do is insertions and lookups, go with a hash table. If you need to solve more complex problems such as prefix-related queries, then a trie might be the better solution. 

 像word search II就是跟前缀有关,如果dfs发现当前形成的前缀都不在字典中,就没必要再搜索下去了,所以用trie不用hashSet

 

Easy version of implement Trie. TrieNode only contains TrieNode[] children, and boolean isWord two fields

 1 class Trie {
 2     class TrieNode {
 3         TrieNode[] children;
 4         boolean isWord;
 5         public TrieNode() {
 6             this.children = new TrieNode[26];
 7             this.isWord = false;
 8         }
 9     }
10     
11     TrieNode root;
12 
13     /** Initialize your data structure here. */
14     public Trie() {
15         this.root = new TrieNode(); 
16     }
17     
18     /** Inserts a word into the trie. */
19     public void insert(String word) {
20         if (word == null || word.length() == 0) return;
21         TrieNode cur = this.root;
22         for (int i = 0; i < word.length(); i ++) {
23             if (cur.children[word.charAt(i) - 'a'] == null) {
24                 cur.children[word.charAt(i) - 'a'] = new TrieNode();
25             } 
26             cur = cur.children[word.charAt(i) - 'a'];
27         }
28         cur.isWord = true;
29     }
30     
31     /** Returns if the word is in the trie. */
32     public boolean search(String word) {
33         TrieNode cur = this.root;
34         for (int i = 0; i < word.length(); i ++) {
35             if (cur.children[word.charAt(i) - 'a'] == null) return false;
36             cur = cur.children[word.charAt(i) - 'a'];
37         }
38         return cur.isWord;
39     }
40     
41     /** Returns if there is any word in the trie that starts with the given prefix. */
42     public boolean startsWith(String prefix) {
43         TrieNode cur = this.root;
44         for (int i = 0; i < prefix.length(); i ++) {
45             if (cur.children[prefix.charAt(i) - 'a'] == null) return false;
46             cur = cur.children[prefix.charAt(i) - 'a'];
47         }
48         return true;
49     }
50 }

 

Older version, TrieNode also has num and val fields, which might not be that useful.

 1 class TrieNode {
 2     // Initialize your data structure here.
 3     int num; //How many words go through this TrieNode
 4     TrieNode[] son; //collection of sons
 5     boolean isEnd;
 6     char val;
 7     
 8     public TrieNode() {
 9         this.num = 0;
10         this.son = new TrieNode[26];
11         this.isEnd = false;
12     }
13 }
14 
15 public class Trie {
16     private TrieNode root;
17 
18     public Trie() {
19         root = new TrieNode();
20     }
21 
22     // Inserts a word into the trie.
23     public void insert(String word) {
24         if (word==null || word.length()==0) return;
25         char[] arr = word.toCharArray();
26         TrieNode node = this.root;
27         for (int i=0; i<arr.length; i++) {
28             int pos = (int)(arr[i] - 'a');
29             if (node.son[pos] == null) {
30                 node.son[pos] = new TrieNode();
31                 node.son[pos].num++;
32                 node.son[pos].val = arr[i];
33             }
34             else {
35                 node.son[pos].num++;
36             }
37             node = node.son[pos];
38         }
39         node.isEnd = true;
40     }
41 
42     // Returns if the word is in the trie.
43     public boolean search(String word) {
44         char[] arr = word.toCharArray();
45         TrieNode node = this.root;
46         for (int i=0; i<arr.length; i++) {
47             int pos = (int)(arr[i] - 'a');
48             if (node.son[pos] == null) return false;
49             node = node.son[pos];
50         }
51         return node.isEnd;
52     }
53 
54     // Returns if there is any word in the trie
55     // that starts with the given prefix.
56     public boolean startsWith(String prefix) {
57         char[] arr = prefix.toCharArray();
58         TrieNode node = this.root;
59         for (int i=0; i<arr.length; i++) {
60             int pos = (int)(arr[i] - 'a');
61             if (node.son[pos] == null) return false;
62             node = node.son[pos];
63         }
64         return true;
65     }
66 }
67 
68 // Your Trie object will be instantiated and called as such:
69 // Trie trie = new Trie();
70 // trie.insert("somestring");
71 // trie.search("key");

 

posted @ 2015-12-16 13:45  neverlandly  阅读(526)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3