Skip to content

Commit fef0fdd

Browse files
authored
Merge pull request #67 from Jer3myYu/java-solutions-tries
Java Chapter 12: Tries
2 parents eb4734f + 090fb0d commit fef0fdd

File tree

3 files changed

+186
-0
lines changed

3 files changed

+186
-0
lines changed

java/Tries/DesignATrie.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
class TrieNode {
5+
Map<Character, TrieNode> children;
6+
boolean isWord;
7+
public TrieNode() {
8+
this.children = new HashMap<>();
9+
this.isWord = false;
10+
}
11+
}
12+
13+
public class DesignATrie {
14+
TrieNode root;
15+
16+
public DesignATrie() {
17+
this.root = new TrieNode();
18+
}
19+
20+
public void insert(String word) {
21+
TrieNode node = this.root;
22+
for (char c : word.toCharArray()) {
23+
// For each character in the word, if it's not a child of
24+
// the current node, create a new TrieNode for that
25+
// character.
26+
node.children.putIfAbsent(c, new TrieNode());
27+
node = node.children.get(c);
28+
}
29+
// Mark the last node as the end of a word.
30+
node.isWord = true;
31+
}
32+
33+
public boolean search(String word) {
34+
TrieNode node = this.root;
35+
for (char c : word.toCharArray()) {
36+
// For each character in the word, if it's not a child of
37+
// the current node, the word doesn't exist in the Trie.
38+
if (!node.children.containsKey(c)) {
39+
return false;
40+
}
41+
node = node.children.get(c);
42+
}
43+
// Return whether the current node is marked as the end of the
44+
// word.
45+
return node.isWord;
46+
}
47+
48+
public boolean hasPrefix(String prefix) {
49+
TrieNode node = this.root;
50+
for (char c : prefix.toCharArray()) {
51+
if (!node.children.containsKey(c)) {
52+
return false;
53+
}
54+
node = node.children.get(c);
55+
}
56+
// Once we've traversed the nodes corresponding to each
57+
// character in the prefix, return True.
58+
return true;
59+
}
60+
}

java/Tries/FindAllWordsOnABoard.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
class TrieNode {
7+
Map<Character, TrieNode> children;
8+
String word;
9+
public TrieNode() {
10+
this.children = new HashMap<>();
11+
this.word = null;
12+
}
13+
}
14+
15+
public class FindAllWordsOnABoard {
16+
public List<String> findAllWordsOnABoard(char[][] board, String[] words) {
17+
TrieNode root = new TrieNode();
18+
// Insert every word into the trie.
19+
for (String word : words) {
20+
TrieNode node = root;
21+
for (char c : word.toCharArray()) {
22+
node.children.putIfAbsent(c, new TrieNode());
23+
node = node.children.get(c);
24+
}
25+
node.word = word;
26+
}
27+
List<String> res = new ArrayList<>();
28+
// Start a DFS call from each cell of the board that contains a
29+
// child of the root node, which represents the first letter of a
30+
// word in the trie.
31+
for (int r = 0; r < board.length; r++) {
32+
for (int c = 0; c < board[0].length; c++) {
33+
if (root.children.containsKey(board[r][c])) {
34+
dfs(board, r, c, root.children.get(board[r][c]), res);
35+
}
36+
}
37+
}
38+
return res;
39+
}
40+
41+
private void dfs(char[][] board, int r, int c, TrieNode node, List<String> res) {
42+
// If the current node represents the end of a word, add the word to
43+
// the result.
44+
if (node.word != null) {
45+
res.add(node.word);
46+
// Ensure the current word is only added once.
47+
node.word = null;
48+
}
49+
char temp = board[r][c];
50+
// Mark the current cell as visited.
51+
board[r][c] = '#';
52+
// Explore all adjacent cells that correspond with a child of the
53+
// current TrieNode.
54+
int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
55+
for (int[] d : dirs) {
56+
int nextR = r + d[0];
57+
int nextC = c + d[1];
58+
if (isWithinBounds(nextR, nextC, board) && node.children.containsKey(board[nextR][nextC])) {
59+
dfs(board, nextR, nextC, node.children.get(board[nextR][nextC]), res);
60+
}
61+
}
62+
// Backtrack by reverting the cell back to its original character.
63+
board[r][c] = temp;
64+
}
65+
66+
private boolean isWithinBounds(int r, int c, char[][] board) {
67+
return 0 <= r && r < board.length && 0 <= c && c < board[0].length;
68+
}
69+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
class TrieNode {
5+
Map<Character, TrieNode> children;
6+
boolean isWord;
7+
public TrieNode() {
8+
this.children = new HashMap<>();
9+
this.isWord = false;
10+
}
11+
}
12+
13+
public class InsertAndSearchWordsWithWildcards {
14+
TrieNode root;
15+
16+
public InsertAndSearchWordsWithWildcards() {
17+
this.root = new TrieNode();
18+
}
19+
20+
public void insert(String word) {
21+
TrieNode node = this.root;
22+
for (char c : word.toCharArray()) {
23+
node.children.putIfAbsent(c, new TrieNode());
24+
node = node.children.get(c);
25+
}
26+
node.isWord = true;
27+
}
28+
29+
public boolean search(String word) {
30+
// Start searching from the root of the trie.
31+
return searchHelper(0, word, this.root);
32+
}
33+
34+
private boolean searchHelper(int wordIndex, String word, TrieNode node) {
35+
for (int i = wordIndex; i < word.length(); i++) {
36+
char c = word.charAt(i);
37+
// If a wildcard character is encountered, recursively
38+
// search for the rest of the word from each child node.
39+
if (c == '.') {
40+
for (TrieNode child : node.children.values()) {
41+
// If a match is found, return true.
42+
if (searchHelper(i + 1, word, child)) {
43+
return true;
44+
}
45+
}
46+
return false;
47+
} else if (node.children.containsKey(c)) {
48+
node = node.children.get(c);
49+
} else {
50+
return false;
51+
}
52+
}
53+
// After processing the last character, return true if we've
54+
// reached the end of a word.
55+
return node.isWord;
56+
}
57+
}

0 commit comments

Comments
 (0)