zoukankan      html  css  js  c++  java
  • LeetCode 208. Implement Trie (Prefix Tree)

    原题链接在这里:https://leetcode.com/problems/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.

    题解:

    Trie 是一种数据结构,用来做字典查找,是一种用于快速检索的多叉数结构。例如,英文字母的字典树是26叉数,数字的字典树是10叉树。 

    Trie树的基本性质有三点,归纳为:

      1. 根节点不包含字符,根节点外每一个节点都只包含一个字符。
      2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
      3. 每个节点的所有子节点包含的字符串不相同。

    下面有两种方法,第一种相对简洁

    Time Complexity: insert, O(m). search, O(m). startsWith, O(m). m = word.length().

    Space: O(n*m). n是总共有多少词.

    AC Java:

     1 class Trie {
     2     TrieNode root;
     3     
     4     /** Initialize your data structure here. */
     5     public Trie() {
     6         root = new TrieNode();
     7     }
     8     
     9     /** Inserts a word into the trie. */
    10     public void insert(String word) {
    11         TrieNode p = root;
    12         for(char c : word.toCharArray()){
    13             if(p.next[c-'a'] == null){
    14                 p.next[c-'a'] = new TrieNode();
    15             }
    16             
    17             p = p.next[c-'a'];
    18         }
    19         
    20         p.val = word;
    21     }
    22     
    23     /** Returns if the word is in the trie. */
    24     public boolean search(String word) {
    25         TrieNode p = root;
    26         for(char c : word.toCharArray()){
    27             if(p.next[c-'a'] == null){
    28                 return false;
    29             }
    30             
    31             p = p.next[c-'a'];
    32         }
    33         
    34         return p.val.equals(word);
    35     }
    36     
    37     /** Returns if there is any word in the trie that starts with the given prefix. */
    38     public boolean startsWith(String prefix) {
    39         TrieNode p = root;
    40         for(char c : prefix.toCharArray()){
    41             if(p.next[c-'a'] == null){
    42                 return false;
    43             }
    44             
    45             p = p.next[c-'a'];
    46         }
    47         
    48         return true;
    49     }
    50 }
    51 
    52 class TrieNode{
    53     String val;
    54     TrieNode [] next;
    55     
    56     public TrieNode(){
    57         val = "";
    58         next = new TrieNode[26];
    59     }
    60 }
    61 
    62 /**
    63  * Your Trie object will be instantiated and called as such:
    64  * Trie obj = new Trie();
    65  * obj.insert(word);
    66  * boolean param_2 = obj.search(word);
    67  * boolean param_3 = obj.startsWith(prefix);
    68  */

    第二种方法用的是存是否为叶子节点. 与第一种方法的存val不同,但本质上都是一回事。

    Note: search() 和 startsWith() 有所不同,search时还需要注意跳出loop时是否已经打了Trie树的叶子节点.

    AC Java:

     1 class TrieNode {
     2     //Mark if this node is the end of the word
     3     boolean isLeaf;
     4     HashMap<Character,TrieNode> nexts;
     5     public TrieNode() {
     6         nexts = new HashMap<Character,TrieNode>();
     7     }
     8 }
     9 
    10 public class Trie {
    11     private TrieNode root;
    12     
    13     public Trie() {
    14         root = new TrieNode();
    15     }
    16 
    17     // Inserts a word into the trie.
    18     public void insert(String word) {
    19         TrieNode p = root;
    20         char [] s = word.toCharArray();
    21         int len = s.length;
    22         int i = 0;
    23         //traverse the existing character
    24         while(i<len){
    25             if(p.nexts.containsKey(s[i])){
    26                 p = p.nexts.get(s[i]);
    27                 i++;
    28             }else{
    29                 break;
    30             }
    31         }
    32         //append new nodes
    33         while(i<len){
    34             TrieNode newNode = new TrieNode();
    35             p.nexts.put(s[i],newNode);
    36             p = newNode;
    37             i++;
    38         }
    39         //Set the end of the word
    40         p.isLeaf = true;
    41     }
    42 
    43     // Returns if the word is in the trie.
    44     public boolean search(String word) {
    45         TrieNode p = root;
    46         char [] s = word.toCharArray();
    47         int len = s.length;
    48         int i = 0;
    49         while(i<len){
    50             TrieNode nextNode = p.nexts.get(s[i]);
    51             if(nextNode == null){
    52                 return false;
    53             }
    54             p = nextNode;
    55             i++;
    56         }
    57         //return if this is a leaf node
    58         return p.isLeaf;
    59     }
    60 
    61     // Returns if there is any word in the trie
    62     // that starts with the given prefix.
    63     public boolean startsWith(String prefix) {
    64         TrieNode p = root;
    65         char [] s = prefix.toCharArray();
    66         int len = s.length;
    67         int i = 0;
    68         while(i<len){
    69             TrieNode nextNode = p.nexts.get(s[i]);
    70             if(nextNode == null){
    71                 return false;
    72             }
    73             p = nextNode;
    74             i++;
    75         }
    76         return true;
    77     }
    78 }
    79 
    80 // Your Trie object will be instantiated and called as such:
    81 // Trie trie = new Trie();
    82 // trie.insert("somestring");
    83 // trie.search("key");

    Reference: http://blog.csdn.net/wzy_1988/article/details/45744067#trie树基本实现

  • 相关阅读:
    framework7 底部弹层popup js关闭方法
    div动画旋转效果
    面试题3
    面试题2
    CORS跨域请求[简单请求与复杂请求]
    面试题1
    nginx
    Pycharm配置支持vue语法
    Ajax在jQuery中的应用---加载异步数据
    jQuery开发入门
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4888830.html
Copyright © 2011-2022 走看看