Skip to content

Commit e65811c

Browse files
committed
79. Word Search (공간복잡도 최적화)
1 parent 9afa0f2 commit e65811c

1 file changed

Lines changed: 62 additions & 14 deletions

File tree

word-search/okyungjin.py

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
# 단, 셀은 한번만 사용 가능하다
44

55
# dfs를 통해 백트랙킹으로 정답을 찾도록 구현했다.
6-
# TODO: 시간/공간 복잡도 계산
7-
class Solution:
6+
7+
# L: word 의 길이
8+
# 시간 복잡도: O(m * n * 4^L)
9+
# 공간 복잡도: O(m * n + L)
10+
class SolutionA:
811
def exist(self, board: List[List[str]], word: str) -> bool:
912
row_size = len(board)
1013
col_size = len(board[0])
@@ -13,39 +16,84 @@ def exist(self, board: List[List[str]], word: str) -> bool:
1316
visited = [[False] * col_size for _ in range(row_size)]
1417

1518
def dfs(row, col, str_idx) -> bool:
19+
if str_idx == len(word):
20+
return True
21+
1622
# 종료조건1: 보드의 좌표를 넘어가는 경우
1723
if row < 0 or row >= row_size or col < 0 or col >= col_size:
1824
return False
1925

20-
# 종료조건2: 이미 방문한 경우
21-
if visited[row][col]:
26+
# 종료조건 2: 이미 방문함
27+
# 종료조건 3: 문자열 불일치
28+
if visited[row][col] or board[row][col] != word[str_idx]:
2229
return False
30+
31+
32+
visited[row][col] = True
2333

24-
# 종료조건3: 문자열 불일치
25-
if board[row][col] != word[str_idx]:
26-
return False
34+
# 차례대로 상, 하, 좌, 우의 좌표를 탐색
35+
found = (dfs(row - 1, col, str_idx + 1) or \
36+
dfs(row + 1, col, str_idx + 1) or \
37+
dfs(row, col - 1, str_idx + 1) or \
38+
dfs(row, col + 1, str_idx + 1))
2739

28-
# 정답 발견 시 종료
29-
if str_idx + 1 == len(word):
40+
visited[row][col] = False # 백트래킹
41+
42+
return found
43+
44+
45+
# 시작점을 찾는다
46+
for r in range(row_size):
47+
for c in range(col_size):
48+
if board[r][c] == word[0] and dfs(r, c, 0):
49+
return True
50+
51+
return False
52+
53+
# SolutionA 의 공간복잡도 최적화 버전, visited 제거
54+
# L: word 의 길이
55+
# 시간 복잡도: O(m * n * 4^L)
56+
# 공간 복잡도: O(L)
57+
class Solution:
58+
def exist(self, board: List[List[str]], word: str) -> bool:
59+
VISITED_MARK = '#'
60+
61+
row_size = len(board)
62+
col_size = len(board[0])
63+
64+
def dfs(row, col, str_idx) -> bool:
65+
if str_idx == len(word):
3066
return True
67+
68+
# 종료조건1: 보드의 좌표를 넘어가는 경우
69+
if row < 0 or row >= row_size or col < 0 or col >= col_size:
70+
return False
71+
72+
# 종료조건 2: 이미 방문함
73+
# 종료조건 3: 문자열 불일치
74+
if board[row][col] == VISITED_MARK or board[row][col] != word[str_idx]:
75+
return False
76+
3177

32-
visited[row][col] = True
78+
# VISITED_MARK로 교체하여 방문을 기록
79+
origin_char = board[row][col]
80+
board[row][col] = VISITED_MARK
3381

3482
# 차례대로 상, 하, 좌, 우의 좌표를 탐색
35-
found = dfs(row - 1, col, str_idx + 1) or \
83+
found = (dfs(row - 1, col, str_idx + 1) or \
3684
dfs(row + 1, col, str_idx + 1) or \
3785
dfs(row, col - 1, str_idx + 1) or \
38-
dfs(row, col + 1, str_idx + 1)
86+
dfs(row, col + 1, str_idx + 1))
3987

40-
visited[row][col] = False # 백트래킹
88+
# 원본 문자열로 복원
89+
board[row][col] = origin_char
4190

4291
return found
4392

4493

4594
# 시작점을 찾는다
4695
for r in range(row_size):
4796
for c in range(col_size):
48-
# board[r][c] == word[0] 인 시작점만 호출하도록 해서 최적화
4997
if board[r][c] == word[0] and dfs(r, c, 0):
5098
return True
5199

0 commit comments

Comments
 (0)