|
1 | 1 | class Solution {
|
2 |
| - public List<String> findWords(char[][] board, String[] words) { |
3 |
| - List<String> result = new ArrayList<>(); |
4 |
| - TrieNode root = buildTrie(words); |
5 |
| - |
6 |
| - for (int i = 0; i < board.length; i++) { |
7 |
| - for (int j = 0; j < board[0].length; j++) { |
8 |
| - helper(board, i, j, root, result); |
9 |
| - } |
10 |
| - } |
11 |
| - |
12 |
| - return result; |
| 2 | + public List<String> findWords(char[][] board, String[] words) { |
| 3 | + List<String> result = new ArrayList<>(); |
| 4 | + TrieNode root = buildTrie(words); |
| 5 | + for (int i = 0; i < board.length; i++) { |
| 6 | + for (int j = 0; j < board[0].length; j++) { |
| 7 | + dfs(board, i, j, result, root); |
| 8 | + } |
13 | 9 | }
|
14 |
| - |
15 |
| - private void helper(char[][] board, int i, int j, TrieNode root, List<String> result) { |
16 |
| - if (i < 0 || i >= board.length || j >= board[i].length || j < 0) { |
17 |
| - return; |
18 |
| - } |
19 |
| - |
20 |
| - char c = board[i][j]; |
21 |
| - if (c == '@' || root.next[c - 'a'] == null) { |
22 |
| - return; |
23 |
| - } |
24 |
| - |
25 |
| - root = root.next[c - 'a']; |
26 |
| - if (root.word != null) { |
27 |
| - result.add(root.word); |
28 |
| - root.word = null; |
| 10 | + return result; |
| 11 | + } |
| 12 | + |
| 13 | + private TrieNode buildTrie(String[] words) { |
| 14 | + TrieNode root = new TrieNode(); |
| 15 | + for (String word : words) { |
| 16 | + TrieNode temp = root; |
| 17 | + for (char c : word.toCharArray()) { |
| 18 | + if (temp.children[c - 'a'] == null) { |
| 19 | + temp.children[c - 'a'] = new TrieNode(); |
29 | 20 | }
|
30 |
| - |
31 |
| - // Choose |
32 |
| - board[i][j] = '@'; |
33 |
| - |
34 |
| - // Explore |
35 |
| - helper(board, i + 1, j, root, result); |
36 |
| - helper(board, i, j + 1, root, result); |
37 |
| - helper(board, i, j - 1, root, result); |
38 |
| - helper(board, i - 1, j, root, result); |
39 |
| - |
40 |
| - // Un-choose |
41 |
| - board[i][j] = c; |
| 21 | + temp = temp.children[c - 'a']; |
| 22 | + } |
| 23 | + temp.word = word; |
42 | 24 | }
|
| 25 | + return root; |
| 26 | + } |
43 | 27 |
|
44 |
| - private TrieNode buildTrie(String[] words) { |
45 |
| - TrieNode root = new TrieNode(); |
46 |
| - for (String word : words) { |
47 |
| - TrieNode temp =root; |
48 |
| - for (char c : word.toCharArray()) { |
49 |
| - if (temp.next[c - 'a'] == null) { |
50 |
| - temp.next[c - 'a'] = new TrieNode(); |
51 |
| - } |
52 |
| - |
53 |
| - temp = temp.next[c - 'a']; |
54 |
| - } |
55 |
| - |
56 |
| - temp.word = word; |
57 |
| - } |
58 |
| - |
59 |
| - return root; |
| 28 | + private void dfs(char[][] board, int i, int j, List<String> result, TrieNode root) { |
| 29 | + char c = board[i][j]; |
| 30 | + if (c == '#' || root.children[c - 'a'] == null) { |
| 31 | + return; |
60 | 32 | }
|
61 |
| - |
62 |
| - class TrieNode { |
63 |
| - TrieNode[] next = new TrieNode[26]; |
64 |
| - String word; |
| 33 | + root = root.children[c - 'a']; |
| 34 | + if (root.word != null) { |
| 35 | + result.add(root.word); |
| 36 | + root.word = null; |
| 37 | + } |
| 38 | + board[i][j] = '#'; |
| 39 | + triggerDfsIfValid(board, i, j, result, root); |
| 40 | + board[i][j] = c; |
| 41 | + } |
| 42 | + |
| 43 | + private void triggerDfsIfValid(char[][] board, int i, int j, List<String> result, TrieNode root) { |
| 44 | + if (i > 0) { |
| 45 | + dfs(board, i - 1, j, result, root); |
| 46 | + } |
| 47 | + if (j > 0) { |
| 48 | + dfs(board, i, j - 1, result, root); |
| 49 | + } |
| 50 | + if (i < board.length - 1) { |
| 51 | + dfs(board, i + 1, j, result, root); |
| 52 | + } |
| 53 | + if (j < board[0].length - 1) { |
| 54 | + dfs(board, i, j + 1, result, root); |
65 | 55 | }
|
| 56 | + } |
| 57 | + |
| 58 | + class TrieNode { |
| 59 | + TrieNode[] children = new TrieNode[26]; |
| 60 | + String word; |
| 61 | + } |
66 | 62 | }
|
0 commit comments