|
| 1 | +/** |
| 2 | + * |
| 3 | + * 접근 방법 : |
| 4 | + * 1. 행렬 순회하며 word와 첫 번째 문자가 같은지 체크 |
| 5 | + * 2. 같으면 DFS(재귀)로 네 방향(상하좌우)을 탐색한다. |
| 6 | + * - 현재 위치가 유효한지 체크 = 범위 안인가, 문자가 같은가 |
| 7 | + * - 단어 다 찾아서 index가 단어 길이와 같은지 체크 |
| 8 | + * 3. 이미 방문한 노드 제외하기 위해서 네 방향 체크하기 전에 방문 여부 표시하기 |
| 9 | + * 4. 4방향으로 문자 체크하기 |
| 10 | + * 5. 재귀 호출하는 동안 찾지 못한 경우 방문 여부 초기화하기 (backtracking) |
| 11 | + * |
| 12 | + * 시간복잡도 : O(N * M * 4^L) |
| 13 | + * - L는 word의 길이, word 길이만큼 네 방향 체크하니까 O(4^L) |
| 14 | + * 공간복잡도 : O(L) |
| 15 | + * |
| 16 | + * - L는 word의 길이, 찾으려는 단어 길이만큼 재귀 호출되니까 O(L) |
| 17 | + * |
| 18 | + */ |
| 19 | + |
| 20 | +function exist(board: string[][], word: string): boolean { |
| 21 | + const rows = board.length; |
| 22 | + const cols = board[0].length; |
| 23 | + |
| 24 | + const dfs = (x: number, y: number, index: number): boolean => { |
| 25 | + // 종료조건 : 문자를 다 찾은 경우 |
| 26 | + if (index === word.length) return true; |
| 27 | + |
| 28 | + // 범위를 벗어나거나 이미 방문했거나 문자가 다른 경우 |
| 29 | + if (x < 0 || y < 0 || x >= rows || y >= cols || board[x][y] !== word[index]) |
| 30 | + return false; |
| 31 | + |
| 32 | + // 방문 표시 |
| 33 | + const temp = board[x][y]; |
| 34 | + board[x][y] = "#"; |
| 35 | + |
| 36 | + // 4 방향 |
| 37 | + const directions = [ |
| 38 | + [1, 0], |
| 39 | + [0, 1], |
| 40 | + [-1, 0], |
| 41 | + [0, -1], |
| 42 | + ]; |
| 43 | + |
| 44 | + for (const [dx, dy] of directions) { |
| 45 | + if (dfs(x + dx, y + dy, index + 1)) return true; |
| 46 | + } |
| 47 | + |
| 48 | + // 백트래킹 |
| 49 | + board[x][y] = temp; |
| 50 | + return false; |
| 51 | + }; |
| 52 | + |
| 53 | + for (let i = 0; i < rows; i++) { |
| 54 | + for (let j = 0; j < cols; j++) { |
| 55 | + if (word[0] === board[i][j] && dfs(i, j, 0)) return true; |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + return false; |
| 60 | +} |
0 commit comments