forked from srishilesh/Data-Structure-and-Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path208_Implement_Trie
147 lines (133 loc) · 4.27 KB
/
208_Implement_Trie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// https://leetcode.com/problems/implement-trie-prefix-tree/
import java.util.HashMap;
import java.util.Map;
/**
* Date 04/25/2016
* @author Tushar Roy
*
* Insert/delete/search into trie data structure
*
* Reference
* https://en.wikipedia.org/wiki/Trie
*/
public class Trie {
private class TrieNode {
Map<Character, TrieNode> children;
boolean endOfWord;
public TrieNode() {
children = new HashMap<>();
endOfWord = false;
}
}
private final TrieNode root;
public Trie() {
root = new TrieNode();
}
/**
* Iterative implementation of insert into trie
*/
public void insert(String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
TrieNode node = current.children.get(ch);
if (node == null) {
node = new TrieNode();
current.children.put(ch, node);
}
current = node;
}
//mark the current nodes endOfWord as true
current.endOfWord = true;
}
/**
* Recursive implementation of insert into trie
*/
public void insertRecursive(String word) {
insertRecursive(root, word, 0);
}
private void insertRecursive(TrieNode current, String word, int index) {
if (index == word.length()) {
//if end of word is reached then mark endOfWord as true on current node
current.endOfWord = true;
return;
}
char ch = word.charAt(index);
TrieNode node = current.children.get(ch);
//if node does not exists in map then create one and put it into map
if (node == null) {
node = new TrieNode();
current.children.put(ch, node);
}
insertRecursive(node, word, index + 1);
}
/**
* Iterative implementation of search into trie.
*/
public boolean search(String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
TrieNode node = current.children.get(ch);
//if node does not exist for given char then return false
if (node == null) {
return false;
}
current = node;
}
//return true of current's endOfWord is true else return false.
return current.endOfWord;
}
/**
* Recursive implementation of search into trie.
*/
public boolean searchRecursive(String word) {
return searchRecursive(root, word, 0);
}
private boolean searchRecursive(TrieNode current, String word, int index) {
if (index == word.length()) {
//return true of current's endOfWord is true else return false.
return current.endOfWord;
}
char ch = word.charAt(index);
TrieNode node = current.children.get(ch);
//if node does not exist for given char then return false
if (node == null) {
return false;
}
return searchRecursive(node, word, index + 1);
}
/**
* Delete word from trie.
*/
public void delete(String word) {
delete(root, word, 0);
}
/**
* Returns true if parent should delete the mapping
*/
private boolean delete(TrieNode current, String word, int index) {
if (index == word.length()) {
//when end of word is reached only delete if currrent.endOfWord is true.
if (!current.endOfWord) {
return false;
}
current.endOfWord = false;
//if current has no other mapping then return true
return current.children.size() == 0;
}
char ch = word.charAt(index);
TrieNode node = current.children.get(ch);
if (node == null) {
return false;
}
boolean shouldDeleteCurrentNode = delete(node, word, index + 1);
//if true is returned then delete the mapping of character and trienode reference from map.
if (shouldDeleteCurrentNode) {
current.children.remove(ch);
//return true if no mappings are left in the map.
return current.children.size() == 0;
}
return false;
}
}