|
| 1 | +class Solution: |
| 2 | + def exist(self, board: list[list[str]], word: str) -> bool: |
| 3 | + if not board or not board[0]: |
| 4 | + return False |
| 5 | + |
| 6 | + m, n = len(board), len(board[0]) |
| 7 | + |
| 8 | + dx = [-1, 1, 0, 0] |
| 9 | + dy = [0, 0, -1, 1] |
| 10 | + |
| 11 | + def dfs(x, y, index): |
| 12 | + if index == len(word): |
| 13 | + return True |
| 14 | + |
| 15 | + if x < 0 or x >= m or y < 0 or y >= n or board[x][y] != word[index]: |
| 16 | + return False |
| 17 | + |
| 18 | + temp = board[x][y] |
| 19 | + board[x][y] = '#' |
| 20 | + |
| 21 | + for i in range(4): |
| 22 | + nx = x + dx[i] |
| 23 | + ny = y + dy[i] |
| 24 | + if dfs(nx, ny, index + 1): |
| 25 | + return True |
| 26 | + |
| 27 | + board[x][y] = temp |
| 28 | + return False |
| 29 | + |
| 30 | + for i in range(m): |
| 31 | + for j in range(n): |
| 32 | + if board[i][j] == word[0] and dfs(i, j, 0): |
| 33 | + return True |
| 34 | + |
| 35 | + return False |
| 36 | + |
| 37 | +""" |
| 38 | +================================================================================ |
| 39 | +풀이 과정 |
| 40 | +================================================================================ |
| 41 | +
|
| 42 | +[1차 시도] DFS + 방향 배열로 접근 |
| 43 | +──────────────────────────────────────────────────────────────────────────────── |
| 44 | +1. 격자에서 상하좌우로 이동하며 단어를 찾아야 함 |
| 45 | +2. 같은 셀은 한 번만 사용 가능 → 방문 체크 필요 |
| 46 | +3. DFS(깊이 우선 탐색) + 백트래킹으로 풀면 될 것 같음 |
| 47 | +4. 상하좌우 이동을 위한 dx, dy 배열 만들자 |
| 48 | +
|
| 49 | + dx = [-1, 1, 0, 0] |
| 50 | + dy = [0, 0, -1, 1] |
| 51 | +
|
| 52 | +
|
| 53 | +[2차 시도] DFS 함수 구조 설계 |
| 54 | +──────────────────────────────────────────────────────────────────────────────── |
| 55 | +5. dfs(x, y, index) 형태로 현재 위치와 단어의 인덱스를 추적 |
| 56 | +6. base case: |
| 57 | + - index == len(word): 단어 끝까지 찾음 → True |
| 58 | + - 범위 벗어남 or 문자 불일치 → False |
| 59 | +
|
| 60 | + def dfs(x, y, index): |
| 61 | + if index == len(word): |
| 62 | + return True |
| 63 | +
|
| 64 | + if x < 0 or x >= m or y < 0 or y >= n or board[x][y] != word[index]: |
| 65 | + return False |
| 66 | +
|
| 67 | +7. 방문한 셀은 어떻게 표시하지? |
| 68 | +
|
| 69 | +
|
| 70 | +[3차 시도] 방문 표시와 백트래킹 |
| 71 | +──────────────────────────────────────────────────────────────────────────────── |
| 72 | +8. 현재 셀을 '#' 같은 특수 문자로 임시 변경 (방문 표시) |
| 73 | +9. 4방향으로 재귀 탐색 |
| 74 | +10. 탐색 실패 시 원래 값으로 복원 (백트래킹) |
| 75 | +
|
| 76 | + temp = board[x][y] |
| 77 | + board[x][y] = '#' |
| 78 | +
|
| 79 | + for i in range(4): |
| 80 | + nx = x + dx[i] |
| 81 | + ny = y + dy[i] |
| 82 | + if dfs(nx, ny, index + 1): |
| 83 | + return True |
| 84 | +
|
| 85 | + board[x][y] = temp |
| 86 | + return False |
| 87 | +
|
| 88 | +
|
| 89 | +[4차 시도] 조기 종료 최적화 추가 |
| 90 | +──────────────────────────────────────────────────────────────────────────────── |
| 91 | +11. 빈 보드는 바로 False 반환 |
| 92 | +12. 첫 글자가 일치하는 셀에서만 DFS 시작 (불필요한 탐색 방지) |
| 93 | +
|
| 94 | + if not board or not board[0]: |
| 95 | + return False |
| 96 | +
|
| 97 | + for i in range(m): |
| 98 | + for j in range(n): |
| 99 | + if board[i][j] == word[0] and dfs(i, j, 0): |
| 100 | + return True |
| 101 | +
|
| 102 | +
|
| 103 | +[최종 구현] 최적화된 DFS 탐색 |
| 104 | +──────────────────────────────────────────────────────────────────────────────── |
| 105 | +13. 조기 종료로 불필요한 탐색 제거 |
| 106 | +14. 백트래킹으로 방문 상태 관리 |
| 107 | +15. 하나라도 성공하면 즉시 True 반환 |
| 108 | +
|
| 109 | +16. 시간복잡도: O(m * n * 4^L) - 최악의 경우, 조기 종료로 실제로는 더 빠름 |
| 110 | +17. 공간복잡도: O(L) - 재귀 깊이 |
| 111 | +""" |
0 commit comments