|
| 1 | +import java.util.ArrayList; |
| 2 | +import java.util.HashMap; |
| 3 | +import java.util.List; |
| 4 | +import java.util.Map; |
| 5 | + |
| 6 | +public 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 | +} |
0 commit comments