-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDesignAddAndSearchWordsDataStructure.java
138 lines (124 loc) · 4.87 KB
/
DesignAddAndSearchWordsDataStructure.java
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
import java.util.ArrayDeque;
import java.util.Deque;
/**
* LeetCode
* 211. Design Add and Search Words Data Structure
* https://leetcode.com/problems/design-add-and-search-words-data-structure/
* #Medium #Trie
*/
public class DesignAddAndSearchWordsDataStructure {
public static void main(String[] args) {
WordDictionary dict = new WordDictionary();
dict.addWord("bad");
dict.addWord("dad");
dict.addWord("mad");
System.out.println(dict.search("pad")); // false
System.out.println(dict.search("bad")); // true
System.out.println(dict.search(".ad")); // true
System.out.println(dict.search("b..")); // true
}
private static class WordDictionary {
private static class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isTerminal = false;
public String toString() {
return "(" + toString(children) + (isTerminal ? ",T" : "") + ")";
}
private String toString(TrieNode[] children) {
if (children == null) return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < children.length; i++) {
if (children[i] != null) {
sb.append((char) (i + 'a'))
.append(children[i].toString())
.append(',');
}
}
if (sb.length() > 0) {
return sb.substring(0, sb.length() - 1);
}
return sb.toString();
}
}
private static class SearchNode {
TrieNode node;
int i;
public String toString() {
return "{" + i + "}";
}
}
TrieNode head;
/**
* Initialize your data structure here.
*/
public WordDictionary() {
head = new TrieNode();
}
/**
* Adds a word into the data structure.
*/
public void addWord(String word) {
if (word == null || word.isEmpty()) return;
TrieNode node = head;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
TrieNode newNode = node.children[ch - 'a'];
if (newNode == null) {
newNode = new TrieNode();
node.children[ch - 'a'] = newNode;
}
node = newNode;
}
node.isTerminal = true;
// System.out.println(head);
}
/**
* Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter.
*/
public boolean search(String word) {
// System.out.print("search: " + word + ", ");
if (word == null || word.isEmpty()) return false;
SearchNode searchNode = new SearchNode();
searchNode.node = head;
Deque<SearchNode> deq = new ArrayDeque<>();
deq.add(searchNode);
while (!deq.isEmpty()) {
// System.out.println(deq);
searchNode = deq.poll();
// System.out.println("word.length() = " + word.length());
// System.out.println("searchNode.i = " + searchNode.i);
// System.out.println("searchNode.node.isTerminal = " + searchNode.node.isTerminal);
if (searchNode.i == word.length()) {
if (searchNode.node.isTerminal) {
// System.out.println("result: true");
return true;
} else {
continue;
}
}
char ch = word.charAt(searchNode.i);
// System.out.println("ch = " + ch);
if (ch == '.') {
// System.out.print("search in children of: ");
for (int i = 0; i < searchNode.node.children.length; i++) {
if (searchNode.node.children[i] != null) {
// System.out.print("" + (char)(i + 'a') + ", ");
SearchNode sn = new SearchNode();
sn.node = searchNode.node.children[i];
sn.i = searchNode.i + 1;
deq.add(sn);
}
}
} else {
if (searchNode.node.children[ch - 'a'] != null) {
searchNode.node = searchNode.node.children[ch - 'a'];
searchNode.i = searchNode.i + 1;
deq.add(searchNode);
}
}
}
// System.out.println("result: false");
return false;
}
}
}