forked from algorhythms/LintCode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWord Search II.py
139 lines (118 loc) · 4.7 KB
/
Word Search II.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
"""
Given a matrix of lower alphabets and a dictionary. Find all words in the dictionary that can be found in the matrix. A word can start from any position in the matrix and go left/right/up/down to the adjacent position.
Example
Given matrix:
doaf
agai
dcan
and dictionary:
{"dog", "dad", "dgdg", "can", "again"}
return {"dog", "dad", "can", "again"}
"""
__author__ = 'Danyang'
class TrieNode(object):
def __init__(self, char):
self.char = char
self.word = None
self.children = {} # map from char to TrieNode
def __repr__(self):
return repr(self.char)
class Trie(object):
def __init__(self):
self.root = TrieNode(None)
def add(self, word):
word = word.lower()
cur = self.root
for c in word:
if c not in cur.children:
cur.children[c] = TrieNode(c)
cur = cur.children[c]
cur.word = word
class Solution:
directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
def wordSearchII_TLE(self, board, words):
"""
Trie+dfs
pure Trie solution
:param board: a list of lists of 1 length string
:param words: a list of string
:return: a list of string
"""
trie = Trie()
for word in words:
trie.add(word)
ret = set()
visited = set()
for i in xrange(len(board)):
for j in xrange(len(board[0])):
self.dfs(board, i, j, trie.root, visited, ret)
return list(ret)
def dfs(self, board, i, j, parent, visited, ret):
"""
:type parent: TrieNode
"""
c = board[i][j]
visited.add((i, j))
if c in parent.children:
cur = parent.children[c]
if cur.word:
ret.add(cur.word)
for direction in Solution.directions:
row = i+direction[0]
col = j+direction[1]
if 0<=row<len(board) and 0<=col<len(board[0]) and (row, col) not in visited:
self.dfs(board, row, col, cur, visited, ret)
visited.remove((i, j))
def wordSearchII(self, board, words):
"""
Trie+dfs
prune by words, but degenerate to the solution which does not require trie
:param board: a list of lists of 1 length string
:param words: a list of string
:return: a list of string
"""
ret = []
for word in words:
trie = Trie()
trie.add(word)
visited = set()
r = set()
found = False
for i in xrange(len(board)):
if not found:
for j in xrange(len(board[0])):
self.dfs2(board, i, j, trie.root, visited, r)
if len(r)==1: # prune when found a result
ret.append(r.pop())
found = True
break
return ret
def dfs2(self, board, i, j, parent, visited, ret):
"""
prune when found a result
:type parent: TrieNode
"""
c = board[i][j]
visited.add((i, j))
if c in parent.children:
cur = parent.children[c]
if cur.word:
ret.add(cur.word)
for direction in Solution.directions:
row = i+direction[0]
col = j+direction[1]
if 0<=row<len(board) and 0<=col<len(board[0]) and (row, col) not in visited and not ret:
self.dfs2(board, row, col, cur, visited, ret)
visited.remove((i, j))
if __name__=="__main__":
board = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaab"]
words = {"baaaaaaaaaaaaa","a","aa","aaaa","aaaax","abaaabbaz"}
assert Solution().wordSearchII(board, words)==['a', 'aa', 'aaaa', 'baaaaaaaaaaaaa']