-
Notifications
You must be signed in to change notification settings - Fork 0
/
079_word_search.py
120 lines (98 loc) · 3.62 KB
/
079_word_search.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
'''
79. Word Search
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
Example:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
Constraints:
board and word consists only of lowercase and uppercase English letters.
1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3
def exist(self, board: List[List[str]], word: str) -> bool:
'''
class Solution(object):
def exist(self, board, word):
'''
approach:
DFS for the values
TC: O(MN4^S) M = # rows N = # of columns each DFS = calls, so there's O(calls^depth)
SC: O(K)
'''
if not board:
return False
for i in range(len(board)):
for j in range(len(board[0])):
if self.dfs(board, i, j, word):
return True
return False
# check whether can find word, start at (i,j) position
def dfs(self, board, i, j, word):
if len(word) == 0: # all the characters are checked
return True
if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or word[0] != board[i][j]:
return False
tmp = board[i][j] # first character is found, check the remaining part
board[i][j] = "#" # avoid visit agian
# check whether can find "word" along one direction
res = self.dfs(board, i+1, j, word[1:]) or self.dfs(board, i-1, j, word[1:]) \
or self.dfs(board, i, j+1, word[1:]) or self.dfs(board, i, j-1, word[1:])
board[i][j] = tmp
return res
'''
approach 2:
TC: O(N3^L) N is number of cells in board, and L is the length of the word to be matched
SC: O(L) L is the length of the word to be matched
'''
def exist(self, board, word):
"""
:type board: List[List[str]]
:type word: str
:rtype: bool
"""
self.ROWS = len(board)
self.COLS = len(board[0])
self.board = board
for row in range(self.ROWS):
for col in range(self.COLS):
if self.backtrack(row, col, word):
return True
# no match found after all exploration
return False
def backtrack(self, row, col, suffix):
# bottom case: we find match for each letter in the word
if len(suffix) == 0:
return True
# Check the current status, before jumping into backtracking
if row < 0 or row == self.ROWS or col < 0 or col == self.COLS \
or self.board[row][col] != suffix[0]:
return False
ret = False
# mark the choice before exploring further.
self.board[row][col] = '#'
# explore the 4 neighbor directions
for rowOffset, colOffset in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
ret = self.backtrack(row + rowOffset, col + colOffset, suffix[1:])
# break instead of return directly to do some cleanup afterwards
if ret:
break
# revert the change, a clean slate and no side-effect
self.board[row][col] = suffix[0]
# Tried all directions, and did not find any match
return ret
if __name__ == '__main__':
# begin
s = Solution()
print(s.exist([
['A', 'B', 'C', 'E'],
['S', 'F', 'C', 'S'],
['A', 'D', 'E', 'E']
], "ABCCED"))