java中trienode_java 前缀树实现 leetcode 208: Implement Trie (Prefix Tree)

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

1.前缀树的概念

所有含有公共前缀的字符串将挂在树中同一个结点下。实际上trie

简明的存储了存在于串集合中的所有公共前缀。

2.举例说明

假如有这样一个字符串集合

X{bear,bell,bid,bull,buy,sell,stock,stop}

。它的标准

Trie

树如下图:

44453 生成的树如图所示。我们可以在每个节点设置item用于存储一个单词。

3.性质

根节点不包含字符,除根节点外每一个节点都只包含一个字符;

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

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

4.查找

标准 Trie树的查找:

对于英文单词的查找,我们完全可以在内部结点中建立26个元素组成的指针数组。如果要查找a,只需要在内部节点的指针数组中找第0个指针即可(b=第1个指针,随机定位)。时间复杂度为O(1)。

查找过程:假如我们要在上面那棵Trie中查找字符串bull (b-u-l-l)。

(1) 在root结点中查找第(‘b’-‘a’=1)号孩子指针,发现该指针不为空,则定位到第1号孩子结点处——b结点。

(2) 在b结点中查找第(‘u’-‘a’=20)号孩子指针,发现该指针不为空,则定位到第20号孩子结点处——u结点。

(3) … 一直查找到叶子结点出现特殊字符‘$’位置,表示找到了bull字符串

如果在查找过程中终止于内部结点,则表示没有找到待查找字符串。

效率:

对于有n个英文字母的串来说,在内部结点中定位指针所需要花费O(d)时间,d为字母表的大小,英文为26。由于在上面的算法中内部结点指针定位使用了数组随机存储方式,因此时间复杂度降为了O(1)。但是如果是中文字,下面在实际应用中会提到。因此我们在这里还是用O(d)。 查找成功的时候恰好走了一条从根结点到叶子结点的路径。因此时间复杂度为O(d*n)。

但是,当查找集合X中所有字符串两两都不共享前缀时,trie中出现最坏情况。除根之外,所有内部结点都自由一个子结点。此时的查找时间复杂度蜕化为O(d*(n^2)

5.JAVA源代码

class TrieNode {

//存储子节点

TrieNode[] children=new TrieNode[26];

//存储一条记录,即对应一个单词

String item="";

// Initialize your data structure here.

public TrieNode() {

}

}

public class Trie {

private TrieNode root;

public Trie() {

root = new TrieNode();

}

// Inserts a word into the trie.

public void insert(String word) {

TrieNode node=this.root;

for(char c:word.toCharArray())

{

if(node.children[c-'a']==null)

{

node.children[c-'a']=new TrieNode();

}

node=node.children[c-'a'];

}

node.item=word;

}

// Returns if the word is in the trie.

public boolean search(String word) {

TrieNode node=this.root;

for(char c:word.toCharArray())

{

if(node.children[c-'a']==null)

{

return false;

}

node=node.children[c-'a'];

}

return node.item.equals(word);

}

// Returns if there is any word in the trie

// that starts with the given prefix.

public boolean startsWith(String prefix) {

TrieNode node=this.root;

for(char c:prefix.toCharArray())

{

if(node.children[c-'a']==null)

{

return false;

}

node=node.children[c-'a'];

}

return true;

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值