|
| 1 | +import java.util.ArrayList; |
| 2 | +import java.util.List; |
| 3 | + |
| 4 | +class Solution { |
| 5 | + |
| 6 | + private int[] dx = {0, 0, 1, -1}; |
| 7 | + private int[] dy = {1, -1, 0, 0}; |
| 8 | + |
| 9 | + private int m; |
| 10 | + private int n; |
| 11 | + |
| 12 | + class TrieNode { |
| 13 | + // 단어는 영어 소문자만으로 이루어짐 |
| 14 | + TrieNode[] nodes = new TrieNode[26]; |
| 15 | + String word = null; |
| 16 | + } |
| 17 | + |
| 18 | + private void insert(TrieNode root, String word) { |
| 19 | + TrieNode node = root; |
| 20 | + for (char c : word.toCharArray()) { |
| 21 | + int idx = c - 'a'; |
| 22 | + if (node.nodes[idx] == null) { |
| 23 | + node.nodes[idx] = new TrieNode(); |
| 24 | + } |
| 25 | + node = node.nodes[idx]; |
| 26 | + } |
| 27 | + // 단어 |
| 28 | + node.word = word; |
| 29 | + } |
| 30 | + |
| 31 | + public List<String> findWords(char[][] board, String[] words) { |
| 32 | + |
| 33 | + List<String> existingWords = new ArrayList<>(); |
| 34 | + |
| 35 | + // 탐색 최적화를 위해 TrieNode 생성 |
| 36 | + TrieNode root = new TrieNode(); |
| 37 | + for (String word : words) { |
| 38 | + insert(root, word); |
| 39 | + } |
| 40 | + |
| 41 | + m = board.length; |
| 42 | + n = board[0].length; |
| 43 | + |
| 44 | + for (int i = 0; i < m; i++) { |
| 45 | + for (int j = 0; j < n; j++) { |
| 46 | + dfs(board, i, j, root, existingWords); |
| 47 | + } |
| 48 | + } |
| 49 | + |
| 50 | + return existingWords; |
| 51 | + } |
| 52 | + |
| 53 | + private void dfs(char[][] board, int i, int j, TrieNode node, List<String> existingWords) { |
| 54 | + |
| 55 | + char c = board[i][j]; |
| 56 | + |
| 57 | + // 방문 처리 되었거나 TrieNode에 없는 글자라면 탐색 X => Pruning |
| 58 | + if (c == '#' || node.nodes[c - 'a'] == null) { |
| 59 | + return; |
| 60 | + } |
| 61 | + |
| 62 | + node = node.nodes[c - 'a']; |
| 63 | + |
| 64 | + // node의 완성된 단어가 있다면 |
| 65 | + if (node.word != null) { |
| 66 | + existingWords.add(node.word); |
| 67 | + node.word = null; |
| 68 | + } |
| 69 | + |
| 70 | + // 방문 처리 |
| 71 | + board[i][j] = '#'; |
| 72 | + |
| 73 | + for (int idx = 0; idx < 4; idx++) { |
| 74 | + int ni = i + dx[idx]; |
| 75 | + int nj = j + dy[idx]; |
| 76 | + if (isRange(ni, nj)) { |
| 77 | + dfs(board, ni, nj, node, existingWords); |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + board[i][j] = c; |
| 82 | + } |
| 83 | + |
| 84 | + // 탐색 범위 조건 |
| 85 | + private boolean isRange(int i, int j) { |
| 86 | + return i >= 0 && j >= 0 && i < m && j < n; |
| 87 | + } |
| 88 | + |
| 89 | +} |
| 90 | + |
0 commit comments