|
1 | 1 | package g0201_0300.s0211_design_add_and_search_words_data_structure; |
2 | 2 |
|
3 | 3 | // #Medium #String #Depth_First_Search #Design #Trie |
4 | | -// #2022_07_02_Time_445_ms_(96.00%)_Space_104.3_MB_(83.47%) |
| 4 | +// #2023_01_06_Time_308_ms_(99.46%)_Space_284.7_MB_(13.25%) |
5 | 5 |
|
6 | 6 | public class WordDictionary { |
7 | 7 |
|
8 | | - private static class Node { |
9 | | - char value; |
10 | | - boolean isEnd; |
11 | | - Node[] childs; |
12 | | - |
13 | | - Node(char value) { |
14 | | - this.value = value; |
15 | | - this.isEnd = false; |
16 | | - this.childs = new Node[26]; |
17 | | - } |
18 | | - |
19 | | - Node getChild(char ch) { |
20 | | - return this.childs[ch - 'a']; |
21 | | - } |
22 | | - |
23 | | - boolean isChild(char ch) { |
24 | | - return getChild(ch) != null; |
25 | | - } |
| 8 | + public WordDictionary() {} |
26 | 9 |
|
27 | | - void addChild(char ch) { |
28 | | - this.childs[ch - 'a'] = new Node(ch); |
29 | | - } |
| 10 | + private static class Node { |
| 11 | + Node[] kids = new Node[26]; |
| 12 | + boolean isTerminal; |
30 | 13 | } |
31 | | - // dummy value |
32 | | - private Node root = new Node('a'); |
33 | 14 |
|
34 | | - public WordDictionary() { |
35 | | - // empty constructor |
36 | | - } |
| 15 | + private final Node[] root = new Node[26]; |
37 | 16 |
|
38 | 17 | public void addWord(String word) { |
39 | | - Node node = root; |
40 | | - for (int i = 0; i < word.length(); i++) { |
41 | | - char ch = word.charAt(i); |
42 | | - if (!node.isChild(ch)) { |
43 | | - node.addChild(ch); |
| 18 | + int n = word.length(); |
| 19 | + if (root[n] == null) { |
| 20 | + root[n] = new Node(); |
| 21 | + } |
| 22 | + Node node = root[n]; |
| 23 | + for (int i = 0; i < n; i++) { |
| 24 | + int c = word.charAt(i) - 'a'; |
| 25 | + Node kid = node.kids[c]; |
| 26 | + if (kid == null) { |
| 27 | + kid = new Node(); |
| 28 | + node.kids[c] = kid; |
44 | 29 | } |
45 | | - node = node.getChild(ch); |
| 30 | + node = kid; |
46 | 31 | } |
47 | | - node.isEnd = true; |
| 32 | + node.isTerminal = true; |
48 | 33 | } |
49 | 34 |
|
50 | 35 | public boolean search(String word) { |
51 | | - return dfs(this.root, word, 0); |
| 36 | + Node node = root[word.length()]; |
| 37 | + return node != null && dfs(0, node, word); |
52 | 38 | } |
53 | 39 |
|
54 | | - public boolean dfs(Node root, String word, int index) { |
55 | | - if (root == null) { |
| 40 | + private boolean dfs(int i, Node node, String word) { |
| 41 | + int len = word.length(); |
| 42 | + if (i == len) { |
56 | 43 | return false; |
57 | 44 | } |
58 | | - // if reached end of word |
59 | | - if (index == word.length()) { |
60 | | - return root.isEnd; |
61 | | - } |
62 | | - char ch = word.charAt(index); |
63 | | - if (ch == '.') { |
64 | | - for (Node child : root.childs) { |
65 | | - boolean found = dfs(child, word, index + 1); |
66 | | - if (found) { |
| 45 | + char c = word.charAt(i); |
| 46 | + if (c == '.') { |
| 47 | + for (Node kid : node.kids) { |
| 48 | + if (kid == null) { |
| 49 | + continue; |
| 50 | + } |
| 51 | + if (i == len - 1 && kid.isTerminal || dfs(i + 1, kid, word)) { |
67 | 52 | return true; |
68 | 53 | } |
69 | 54 | } |
70 | 55 | return false; |
71 | 56 | } |
72 | | - if (!root.isChild(ch)) { |
| 57 | + Node kid = node.kids[c - 'a']; |
| 58 | + if (kid == null) { |
73 | 59 | return false; |
74 | 60 | } |
75 | | - return dfs(root.getChild(ch), word, index + 1); |
| 61 | + if (i == len - 1) { |
| 62 | + return kid.isTerminal; |
| 63 | + } |
| 64 | + return dfs(i + 1, kid, word); |
76 | 65 | } |
77 | 66 | } |
78 | 67 |
|
|
0 commit comments