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的更多相关文章

  1. Leetcode: Implement Trie (Prefix Tree) && Summary: Trie

    Implement a trie with insert, search, and startsWith methods. Note: You may assume that all inputs a ...

  2. leetcode面试准备:Implement Trie (Prefix Tree)

    leetcode面试准备:Implement Trie (Prefix Tree) 1 题目 Implement a trie withinsert, search, and startsWith m ...

  3. Implement Trie (Prefix Tree) 解答

    Question Implement a trie with insert, search, and startsWith methods. Note:You may assume that all ...

  4. [Swift]LeetCode208. 实现 Trie (前缀树) | Implement Trie (Prefix Tree)

    Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie. ...

  5. 【LeetCode】208. Implement Trie (Prefix Tree)

    Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Note:You ...

  6. [LeetCode] 208. Implement Trie (Prefix Tree) ☆☆☆

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  7. 字典树(查找树) leetcode 208. Implement Trie (Prefix Tree) 、211. Add and Search Word - Data structure design

    字典树(查找树) 26个分支作用:检测字符串是否在这个字典里面插入.查找 字典树与哈希表的对比:时间复杂度:以字符来看:O(N).O(N) 以字符串来看:O(1).O(1)空间复杂度:字典树远远小于哈 ...

  8. 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  ...

  9. 【刷题-LeetCode】208. Implement Trie (Prefix Tree)

    Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Example: ...

随机推荐

  1. P4360 [CEOI2004]锯木厂选址

    P4360 [CEOI2004]锯木厂选址 这™连dp都不是 \(f_i\)表示第二个锯木厂设在\(i\)的最小代价 枚举1号锯木厂 \(f_i=min_{0<=j<i}(\sum_{i= ...

  2. Direct2D处理几何图形之间的碰撞检测(上)

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 Direct2D中支持以下几种类型的几何图形: a.简单几何图形(Simple Geometry):矩形.圆角矩 ...

  3. 微信小程序云开发

    什么是云开发? 云开发是由腾讯云联合微信团队为开发者提供的 包含 云函数.云数据库和云文件存储能力的后端云服务 云开发为开发者提供完整的云端支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 A ...

  4. Unity扩展编辑器一

    将Test1脚本挂在摄像机上 ​ 如图展示 ​ 下面我们需要在代码中动态的编辑它,请在你的Project视图中创建一个Editor文件夹,把MyEditor放进Editor文件夹中 ​ 在OnInsp ...

  5. XSS分类&危害&防御

    XSS(跨站脚本)漏洞是什么? 在网页中插入恶意的js脚本,由于网站没对其过滤,当用户浏览时,就会触发脚本,造成XSS攻击 XSS分类? 1.反射型 用户输入的注入代通过浏览器传入到服务器后,又被目标 ...

  6. 零基础学python之函数与模块(附详细的代码和安装发布文件过程)

    代码重用——函数与模块 摘要:构建函数,创建模块,安装发布文件,安装pytest和PEP 8插件,确认PEP8兼容性以及纠错 重用代码是构建一个可维护系统的关键. 代码组是Python中对块的叫法. ...

  7. SQL Operations Studio的安装和使用

    之前管理和访问SQL SERVER使用的自然是SSMS,功能确实很强大的一个数据库图形化管理软件,但是SSMS有个问题就是体积超级大,启动速度也就比较慢.今天我正好要学习一些T-SQL的内容,在微软的 ...

  8. WinDbg使用学习

    拿到软件崩溃之后产生的crash文件,后缀名为dump 使用winDbg的File-----> Open Crash Dump 打开Crash文件 File---------> Symbo ...

  9. ef5 数据库操作

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. can总线实现stm32的IAP

    使用stm32f105rct6的can通信做IAP,实现固件的远程更新功能.IAP的实现包括两个程序:BootLoader和应用程序.启动过程先启动BootLoader,等待1s,若接收到烧写指令则开 ...