资讯专栏INFORMATION COLUMN

[Leetcode] Implement Trie 实现前缀树

jsliang / 1255人阅读

摘要:压缩前缀树其实就是将所有只有一个子节点的节点合并成一个,以减少没有意义的类似链表式的链接。然后我们开始遍历这个前缀树。

Implement Trie

</>复制代码

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

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

哈希表法 复杂度

时间 插入和查询都是O(K) K是词的长度 空间 O(NK) N是字典里词的个数

思路

前缀树的具体讲解请戳这篇博客。这里我们实现树节点时使用了哈希表来映射字母和子节点的关系。
insert():对于插入操作,我们遍历字符串同时,根据上一个节点的哈希表来找到下一个节点,直到哈希表中没有相应的字母,我们就新建一个节点。然后从这个新建节点开始,用同样的方法把剩余的字母添加完。记住最后一个字母要添加叶子节点的标记,表明这个词到此已经完整了。
search():对于搜索操作,我们也是遍历字符串,然后根据每个节点的哈希表找到路径,最后返回该字符串最后一个字母所在节点。如果中途有找不到路径的情况就直接返回null,如果找到了最后的节点,如果它也是叶子结点的话,就说明找到了。
startWith():使用和search(),一样的方法,只是我们返回的节点不用判断是否是叶子节点。只要找到就行。

代码

</>复制代码

  1. class TrieNode {
  2. // Initialize your data structure here.
  3. HashMap children = new HashMap();
  4. boolean isLeaf = false;
  5. char c;
  6. public TrieNode(){}
  7. public TrieNode(char c) {
  8. this.c = c;
  9. }
  10. }
  11. public class Trie {
  12. private TrieNode root;
  13. public Trie() {
  14. root = new TrieNode();
  15. }
  16. // Inserts a word into the trie.
  17. public void insert(String word) {
  18. HashMap children = root.children;
  19. for(int i = 0; i < word.length(); i++){
  20. TrieNode next;
  21. // 如果已有该字母的节点,则转向该节点
  22. if(children.containsKey(word.charAt(i))){
  23. next = children.get(word.charAt(i));
  24. } else {
  25. // 如果没有该字母的节点,就新建一个节点
  26. next = new TrieNode(word.charAt(i));
  27. children.put(word.charAt(i), next);
  28. }
  29. children = next.children;
  30. if(i == word.length() - 1){
  31. next.isLeaf = true;
  32. }
  33. }
  34. }
  35. // Returns if the word is in the trie.
  36. public boolean search(String word) {
  37. TrieNode res = searchNode(word);
  38. if(res != null && res.isLeaf){
  39. return true;
  40. } else {
  41. return false;
  42. }
  43. }
  44. // Returns if there is any word in the trie
  45. // that starts with the given prefix.
  46. public boolean startsWith(String prefix) {
  47. return searchNode(prefix) != null;
  48. }
  49. private TrieNode searchNode(String word){
  50. HashMap children = root.children;
  51. TrieNode next = null;
  52. for(int i = 0; i < word.length(); i++){
  53. if(children.containsKey(word.charAt(i))){
  54. next = children.get(word.charAt(i));
  55. children = next.children;
  56. } else {
  57. return null;
  58. }
  59. }
  60. return next;
  61. }
  62. }
  63. // Your Trie object will be instantiated and called as such:
  64. // Trie trie = new Trie();
  65. // trie.insert("somestring");
  66. // trie.search("key");
后续 Follow Up

Q:给定一个标准前缀树,请写一段程序将其压缩。
A:压缩前缀树其实就是将所有只有一个子节点的节点合并成一个,以减少没有意义的类似链表式的链接。

首先我们先将TrieNode稍微改一下。让它能存字符串而不只是字母。

</>复制代码

  1. class TrieNode {
  2. // Initialize your data structure here.
  3. HashMap children = new HashMap();
  4. boolean isLeaf = false;
  5. String str;
  6. public TrieNode(){}
  7. public TrieNode(char c) {
  8. this.str = String.valueOf(c);
  9. }
  10. }

然后我们开始遍历这个前缀树。

</>复制代码

  1. public void compressTrie(Trie t){
  2. compress(t.getRoot());
  3. }
  4. private void compress(TrieNode n){
  5. if(n == null) return;
  6. if(n.children.size()==1){
  7. TrieNode next = n.children.get(n.children.keySet().iterator().next());
  8. n.str = n.str + next.str;
  9. n.children = next.children;
  10. compress(next);
  11. } else {
  12. for(String key: n.children.keySet()){
  13. compress(n.children.get(key));
  14. }
  15. }
  16. }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64494.html

相关文章

  • [LintCode/LeetCode] Implement Trie

    摘要:首先,我们应该了解字典树的性质和结构,就会很容易实现要求的三个相似的功能插入,查找,前缀查找。既然叫做字典树,它一定具有顺序存放个字母的性质。所以,在字典树的里面,添加,和三个参数。 Problem Implement a trie with insert, search, and startsWith methods. Notice You may assume that all i...

    付永刚 评论0 收藏0
  • 208-实现 Trie (前缀)

    摘要:前言前缀树是一种很常用的数据结构,例如我们常用的数据库索引。而关于前缀树的介绍,由于中国有关于前缀树的教程,我就不班门弄斧了,我的答案也是参考教程的思路去解答,希望可以给大家一个参考。下面是原题目实现一个前缀树,包含和这三个操作。 前言 前缀树是一种很常用的数据结构,例如我们常用的数据库索引。而关于前缀树的介绍,由于LeetCode中国有关于前缀树的教程,我就不班门弄斧了,我的答案也是...

    antyiwei 评论0 收藏0
  • [Leetcode] Word Search 单词搜索

    摘要:我们可以先用待查单词建立一个字典树,这样我们在从矩阵中某个点开始深度优先搜索时,可以直接用字典树判断当前组成的字符串是否是某个单词的前缀。字典树同样也提供接口,所以同样可以用于判断是否已经搜索到这个词了。 Word Search I 更新的思路与解法请访问:https://yanjia.me/zh/2018/11/... Given a 2D board and a word, f...

    objc94 评论0 收藏0
  • javascript 前缀Trie

    摘要:很容易看出,前缀最坏情况下的查找也快过二叉搜索树。这种压缩后的被唤作前缀压缩,或直接叫前缀树,字典树。最长公共前缀和的最长公共前缀是,遍历字典树到字母时,此时这些单词的公共前缀是。 引子 前缀Trie, 又叫字符Tire, trie来自单词retrieval, 一开始念作tree,后来改念try, 毕竟它与树是不一样的东西。网上许多文章都搞混了trie与树。 trie是通过边来储存字符...

    xiaochao 评论0 收藏0
  • 以太坊数据结构MPT

    摘要:是以太坊存储数据的核心数据结构,它是由和结合的一种树形结构,理解有助于我们更好的理解以太坊的数据存储。所以就有了树压缩前缀树,后面会介绍到,也被称为,中文名称默克尔树,主要用于数据集较大时的文件校验。   MPT(Merkle Patricia Tries)是以太坊存储数据的核心数据结构,它是由Merkle Tree和Patricia Tree结合的一种树形结构,理解MPT有助于我们更...

    Honwhy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<