208. Implement Trie (Prefix Tree)

题目链接:https://leetcode.com/problems/implement-trie-prefix-tree/

实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:

Trie trie = new Trie();

trie.insert("apple");
trie.search("apple");   // 返回 true
trie.search("app");     // 返回 false
trie.startsWith("app"); // 返回 true
trie.insert("app");   
trie.search("app");     // 返回 true
说明:

你可以假设所有的输入都是由小写字母 a-z 构成的。
保证所有输入均为非空字符串。

 

思路:

前缀树,又称字典树。

以一张图来看什么是前缀树:

 

Trie树,又叫字典树、前缀树(Prefix Tree)、单词查找树或键树,是一种多叉树结构。如下图:

 


上图是一棵Trie树,表示了关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。从上图可以归纳出Trie树的基本性质: 
①根节点不包含字符,除根节点外的每一个子节点都包含一个字符。 
②从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。 
③每个节点的所有子节点包含的字符互不相同。 
④从第一字符开始有连续重复的字符只占用一个节点,比如上面的to,和ten,中重复的单词t只占用了一个节点。

前缀树的应用
1、前缀匹配 
2、字符串检索 
3、词频统计 
4、字符串排序

 

回到此题,由于只包含26个小写字母,于是我们构造一个TrieNode的数据结构,它的域中包含26个字母的TrieNode类型的数组

以及单词是否结束的IsEnd(Boolean类型)

然后在trie类中定义一个root节点,每次的insert、search。startwith都是从root节点开始的。

 

插入apple:

最初temp=root;

1  .  先是'a',由于最初初始化的root.children['a'-'a']即root.children[0]==null,所以在children[0]的位置重新定义一个TrieNode

      此时把temp更新为root.children[0]即一个新的TrieNode节点,

2  .  再是'p'同理,temp更新为root.children[0].children['p'-'a'],也就是更深层的一个新的TrieNode节点

3  .  再是'p',temp更新为root.children[0].children['p'-'a'].children['p'-'a'],

4  .  'l' ,temp更新为root.children[0].children['p'-'a'].children['p'-'a'].children['l'-'a'],

5  .  'e',temp更新为root.children[0].children['p'-'a'].children['p'-'a'].children['l'-'a'].children['e'-'a'],

此时这个单词就结束了,在最后的temp所指向的节点就是

root.children[0].children['p'-'a'].children['p'-'a'].children['l'-'a'].children['e'-'a'],把它的isEnd域更改为true。

余下的思路同理可以应用到search和startwith操作上面。

 

AC  73 ms, faster than 98.77% of Java online submissions for Implement Trie (Prefix Tree).

class TrieNode{
    TrieNode[] children;
    boolean isEnd;
    public TrieNode(){
        children=new TrieNode[26];
        isEnd=false;
    }
}
class Trie {
    
    TrieNode root;
    
    /** Initialize your data structure here. */
    public Trie() {
        root=new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    public void insert(String word) {
        TrieNode temp=root;
        for(char c: word.toCharArray()){
            if(temp.children[c-'a']==null){
                temp.children[c-'a']=new TrieNode();
            }
            temp=temp.children[c-'a'];
        }
        temp.isEnd=true;
    }
    
    /** Returns if the word is in the trie. */
    public boolean search(String word) {
        TrieNode temp=root;
        for(char c:word.toCharArray()){
            if(temp.children[c-'a']==null)
                return false;
            else
                temp=temp.children[c-'a'];
        }
        return temp.isEnd;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    public boolean startsWith(String prefix) {
        TrieNode temp=root;
        for(char c: prefix.toCharArray()){
            if(temp.children[c-'a']==null)
                return false;
            else
                temp=temp.children[c-'a'];
        }
        return true;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值