Implement Trie and find longest prefix string list
package leetcode; import java.util.ArrayList;
import java.util.List; class TrieNode{
Boolean isWord;//true if path till this node represent a string.
Integer freq;//numbers of strings share the same prefix
Character nodeChar;//character for this node
ArrayList<TrieNode> childNodes;
public TrieNode(char c){
childNodes = new ArrayList<TrieNode>();
this.nodeChar = c;
this.freq = 1;
this.isWord = false;
}
public TrieNode(){
childNodes = new ArrayList<TrieNode>();
this.nodeChar = null;
this.freq = 0;
this.isWord = false;
}
} class Prefix{
TrieNode root;
String prefix;
public Prefix(TrieNode root, String s){
this.root = root;
this.prefix = s;
}
} public class Trie {
/*
Trie is an efficient information retrieval data structure.
Using trie, search complexities can be brought to optimal limit (key length).
If we store keys in binary search tree, a well balanced BST will need time proportional to M * log N,
where M is maximum string length and N is number of keys in tree.
Using trie, we can search the key in O(M) time.
However the penalty is on trie storage requirements.
*/
TrieNode root;
public Trie(){
root = new TrieNode();
} public void insert(String s){
if(s == null || s.length() == 0) return;
TrieNode tmp = root;
tmp.freq ++;// prefix freq ++
for(int i = 0; i < s.length(); i ++){
Boolean hasNode = false;
for(int j = 0; j < tmp.childNodes.size(); j ++){
if(tmp.childNodes.get(j).nodeChar == s.charAt(i)){
tmp = tmp.childNodes.get(j);
tmp.freq ++;
hasNode = true;
break;
}
}
if(hasNode == false){
TrieNode newNode = new TrieNode(s.charAt(i));
tmp.childNodes.add(newNode);
tmp = newNode;
}
}
tmp.isWord = true;
} public Boolean searchString(String s){
if(s == null || s.length() == 0) return false;
TrieNode tmp = root;
for(int i = 0; i < s.length(); i ++){
Boolean containsChar = false;
for(int j = 0; j < tmp.childNodes.size(); j ++){
if(tmp.childNodes.get(j).nodeChar == s.charAt(i)){
tmp = tmp.childNodes.get(j);
containsChar = true;
break;
}
}
if(containsChar == false){
return false;
}
}
return tmp.isWord == true;
} /*
* During delete operation we delete the key in bottom up manner using recursion. The following are possible conditions when deleting key from trie,
* 1. Key may not be there in trie. Delete operation should not modify trie.
* 2. Key present as unique key (no part of key contains another key (prefix), nor the key itself is prefix of another key in trie). Delete all the nodes.
* 3. Key is prefix key of another long key in trie. Unmark the leaf node.
* 4. Key present in trie, having atleast one other key as prefix key. Delete nodes from end of key until first leaf node of longest prefix key.
*/
public void delete(String s){
if(searchString(s) == false) return;
TrieNode tmp = root;
if(tmp.freq == 1){
tmp.childNodes.remove(0);
tmp.freq = 0;
return;
}
for(int i = 0; i < s.length(); i ++){
for(int j = 0; j < tmp.childNodes.size(); j ++){
if(tmp.childNodes.get(j).nodeChar == s.charAt(i)){
if(tmp.childNodes.get(j).freq == 1){
tmp.childNodes.remove(j);
tmp.freq --;
return;
}else{
tmp.childNodes.get(j).freq --;
tmp = tmp.childNodes.get(j);
}
break;
}
}
}
tmp.isWord = false; } //find a list of string in the dictionary, which contains the longest prefix with the target string
public List<String> findAllStringWithSameLongestPrefix(String s){
Prefix tmp = findLongestPrefix(s);
List<String> result = new ArrayList<String>();
if(tmp.root.equals(root)) return result;
findAllStringInSubTree(tmp.root, new StringBuilder(tmp.prefix), result);
return result;
} private Prefix findLongestPrefix(String s){
TrieNode tmp = root;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i ++){
Boolean containsChar = false;
for(int j = 0; j < tmp.childNodes.size(); j ++){
if(tmp.childNodes.get(j).nodeChar == s.charAt(i)){
sb.append(s.charAt(i));
tmp = tmp.childNodes.get(j);
containsChar = true;
break;
}
}
if(containsChar == false){
return new Prefix(tmp, sb.toString());
}
}
return new Prefix(tmp, s);
} private void findAllStringInSubTree(TrieNode root, StringBuilder sb, List<String> result){
if(root.isWord == true){
result.add(sb.toString());
}
for(int i = 0; i < root.childNodes.size(); i ++){
TrieNode tmp = root.childNodes.get(i);
sb.append(tmp.nodeChar);
findAllStringInSubTree(tmp, new StringBuilder(sb), result);
sb.deleteCharAt(sb.length() - 1);
}
} public static void main(String[] args){
Trie trie = new Trie();
System.out.println("insert string into Trie:");
System.out.println("a, aq, ab, abb, aa, bbd, bd, ba, abc");
trie.insert("a");
trie.insert("aq");
trie.insert("ab");
trie.insert("abb");
trie.insert("aa");
trie.insert("bbd");
trie.insert("bd");
trie.insert("ba");
trie.insert("abc");
System.out.println("search string in Trie:");
System.out.println("abb: " + trie.searchString("abb"));
System.out.println("bd: " + trie.searchString("bd"));
System.out.println("bda: " + trie.searchString("bda"));
System.out.println("strings start with a:");
List<String> list1 = trie.findAllStringWithSameLongestPrefix("a");
for(int i = 0; i < list1.size(); i ++){
System.out.println(list1.get(i));
}
System.out.println("strings start with b:");
List<String> list2 = trie.findAllStringWithSameLongestPrefix("b");
for(int i = 0; list2 != null && i < list2.size(); i ++){
System.out.println(list2.get(i));
}
System.out.println("strings start with ab:");
List<String> list3 = trie.findAllStringWithSameLongestPrefix("ab");
for(int i = 0; i < list3.size(); i ++){
System.out.println(list3.get(i));
}
System.out.println("strings start with abcdef:");
List<String> list4 = trie.findAllStringWithSameLongestPrefix("abcdef");
for(int i = 0; list4 != null && i < list4.size(); i ++){
System.out.println(list4.get(i));
}
System.out.println("delete string from trie:");
trie.delete("ab");
System.out.println(trie.searchString("ab"));
System.out.println(trie.searchString("abb"));
}
}
Output:
insert string into Trie:
a, aq, ab, abb, aa, bbd, bd, ba, abc
search string in Trie:
abb: true
bd: true
bda: false
strings start with a:
a
aq
ab
abb
abc
aa
strings start with b:
bbd
bd
ba
strings start with ab:
ab
abb
abc
strings start with abcdef:
abc
delete string from trie:
false
true
Implement Trie and find longest prefix string list的更多相关文章
- Leetcode: Implement Trie (Prefix Tree) && Summary: Trie
Implement a trie with insert, search, and startsWith methods. Note: You may assume that all inputs a ...
- leetcode面试准备:Implement Trie (Prefix Tree)
leetcode面试准备:Implement Trie (Prefix Tree) 1 题目 Implement a trie withinsert, search, and startsWith m ...
- Implement Trie (Prefix Tree) 解答
Question Implement a trie with insert, search, and startsWith methods. Note:You may assume that all ...
- [Swift]LeetCode208. 实现 Trie (前缀树) | Implement Trie (Prefix Tree)
Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie. ...
- 【LeetCode】208. Implement Trie (Prefix Tree)
Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Note:You ...
- [LeetCode] 208. Implement Trie (Prefix Tree) ☆☆☆
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- 字典树(查找树) leetcode 208. Implement Trie (Prefix Tree) 、211. Add and Search Word - Data structure design
字典树(查找树) 26个分支作用:检测字符串是否在这个字典里面插入.查找 字典树与哈希表的对比:时间复杂度:以字符来看:O(N).O(N) 以字符串来看:O(1).O(1)空间复杂度:字典树远远小于哈 ...
- LeetCode208 Implement Trie (Prefix Tree). LeetCode211 Add and Search Word - Data structure design
字典树(Trie树相关) 208. Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith ...
- 【刷题-LeetCode】208. Implement Trie (Prefix Tree)
Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Example: ...
随机推荐
- 2069: [POI2004]ZAW
2069: [POI2004]ZAW 链接 题意: 给定一张带权图(边是双向的,但不同方向长度不同).求从1出发,至少经过除1外的一个点,再回到1的最短路.点和边不能重复经过. n≤5000,m≤10 ...
- Fortran的数组与指针
个人理解,欢迎指正 指针就是记录数据的内存地址的变量.指针可以指向单个变量,也可以指向数组. 数组是一个概念,是若干个类型相同的元素的有序集合.在Fortran语言中,数组中存放的元素,可以是整数,实 ...
- JS截图(html2canvas)
JS截图(html2canvas) • 引入js <script type="text/javascript" src="js/html2canvas.js&quo ...
- Linux入门基础(七):Linux软件管理基础
源代码形式 绝大多数开源软件都是直接以源代码形式发布 源代码一般会被打包成tar.gz的归档压缩文件 程序源代码需要编译成为二进制形式之后才能够运行 源代码基本编译流程 : ./configure 检 ...
- 高级PHP工程师所应该具备的专业素养
初次接触PHP,就为他的美所折服,于是一发不可收拾. 很多面试,很多人员能力要求都有“PHP高级工程师的字眼”,如果您真心喜欢PHP,并且您刚起步,那么我简单说说一个PHP高级工程师所应该具备的,希望 ...
- Datawhale MySQL 训练营 Task5
数据导入导出 导入table http://www.runoob.com/mysql/mysql-database-import.html 导出table http://www.runoob.com/ ...
- Netty源码分析第5章(ByteBuf)---->第4节: PooledByteBufAllocator简述
Netty源码分析第五章: ByteBuf 第四节: PooledByteBufAllocator简述 上一小节简单介绍了ByteBufAllocator以及其子类UnPooledByteBufAll ...
- 利用saltstack一键部署多台zookeeper
以上是saltstack上面sls文件存放zookeeper的路径和文件 以上是入口文件把文件夹做成包 重要安装配置在zoo.sls,以下是该sls的内容 zookeeper: file.manage ...
- asp.net core如何修改程序监听的端口
asp.net core 默认监听的5000和5001端口,要修改为其他端口有几种方法. 1.硬编码.优点是直观,缺点是每次修改端口都得重新编译程序. public class Program { p ...
- linux压缩相关
tar命令 tar是打包,即把好多东西放在一个大文件里面,之后再压缩:当然也可以解包 tar的几个参数说明: -c 创建一个新的包 -x 将包里的文件还原出来 -t 显示包内文件的列表 -f 指定要处 ...