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: ...
随机推荐
- OpenStack入门篇(二十)之实现阿里云ESC多FLAT网络
1.给两台虚拟机增加网卡,使用仅主机模式,网段为:192.168.57.0/24 2.修改两台主机网卡配置 [root@linux-node1 ~]# cp /etc/sysconfig/networ ...
- vue中使用定时器时this指向问题
在写一个很小的demo时,用的普通函数写法,没有用es6箭头函数,发现this变化了,后来查找到了问题所在: 箭头函数中的this指向是固定不变(定义函数时的指向),在vue中指向vue 普通函数中的 ...
- JAVA 删除指定目录下指定文件类型的所有文件
public class DelFile { public static void main(String[] args) { File file = new File("C:\\DETEC ...
- JS ,substr、 substring、charAt方法的区别
JS 截取字符串substr 和 substring方法的区别,需要的朋友可以参考下,根据需要自行选择. substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.subs ...
- Vue实例 中的常用配置项
创建Vue实例时,使用 new Vue ({//配置项}) 或者 组件定义中 export default {//配置项},所有的Vue组件都是Vue实例,并且接受相同的选项对象(一些根实例特有的选项 ...
- 使用electron开发一个h5的客户端应用创建http服务模拟后台接口mock
使用electron开发一个h5的客户端应用创建http服务模拟后端接口mock 在上一篇<electron快速开始>里讲述了如何快速的开始一个electron的应用程序,既然electr ...
- Unity 几何着色器
Unity 几何着色器 shaderGeometry Shader几何着色器 Unity 几何着色器 如果学习不能带来价值,那将毫无意义 简介 在顶点和片段着色器之间有一个可选的着色器,叫做几 ...
- 011 --Mysql中特定查询
1.优化COUNT()查询 COUNT()可能是被大家误解最多的函数了,它有两种不同的作用,其一是统计某个列值的数量,其二是统计行数.统计列值时,要求列值是非空的,它不会统计NULL.如果确认括号中的 ...
- linux执行命令返回码释义
Linux 操作系统错误代码解释 0.错误代码1-10 OS error code 0: Success 操作系统错误代码0:成功 OS error code 1: Operation not per ...
- Vue+webpack报错: listen EADDRINUSE: address already in use :::8080
如果本地运行多个vue+webpack项目会报错:listen EADDRINUSE: address already in use :::8080: 提示含义:地址端口已经被占用 注:8080指的是 ...