1
+ import unittest
1
2
'''
2
3
Given a matrix of words and a list of words to search, return a list of words that exists in the board
3
4
This is Word Search II on LeetCode
11
12
12
13
words = ["oath","pea","eat","rain"]
13
14
14
- print findWords(board, words)
15
15
'''
16
16
17
- def findWords (board , words ):
18
- #make trie
17
+ def find_words (board , words ):
18
+ # make a trie structure that is essentially dictionaries of dictionaries that map each character to a potential next character
19
19
trie = {}
20
20
for word in words :
21
21
curr_trie = trie
@@ -25,15 +25,29 @@ def findWords(board, words):
25
25
curr_trie = curr_trie [char ]
26
26
curr_trie ['#' ] = '#'
27
27
28
+ # result is a set of found words since we do not want repeats
28
29
result = set ()
29
30
used = [[False ]* len (board [0 ]) for _ in range (len (board ))]
30
31
31
32
for i in range (len (board )):
32
33
for j in range (len (board [0 ])):
33
- find (board , i , j , trie , '' , used , result )
34
+ backtrack (board , i , j , trie , '' , used , result )
34
35
return list (result )
35
36
36
- def find (board , i , j , trie , pre , used , result ):
37
+ '''
38
+ backtrack tries to build each words from the board and return all words found
39
+ @param: board, the passed in board of characters
40
+ @param: i, the row index
41
+ @param: j, the column index
42
+ @param: trie, a trie of the passed in words
43
+ @param: pre, a buffer of currently build string that differs by recursion stack
44
+ @param: used, a replica of the board except in booleans to state whether a character has been used
45
+ @param: result, the resulting set that contains all words found
46
+
47
+ @return: list of words found
48
+ '''
49
+
50
+ def backtrack (board , i , j , trie , pre , used , result ):
37
51
if '#' in trie :
38
52
result .add (pre )
39
53
@@ -42,8 +56,56 @@ def find(board, i, j, trie, pre, used, result):
42
56
43
57
if not used [i ][j ] and board [i ][j ] in trie :
44
58
used [i ][j ]= True
45
- find (board ,i + 1 ,j ,trie [board [i ][j ]],pre + board [i ][j ], used , result )
46
- find (board ,i ,j + 1 ,trie [board [i ][j ]],pre + board [i ][j ], used , result )
47
- find (board ,i - 1 ,j ,trie [board [i ][j ]],pre + board [i ][j ], used , result )
48
- find (board ,i ,j - 1 ,trie [board [i ][j ]],pre + board [i ][j ], used , result )
59
+ backtrack (board ,i + 1 ,j ,trie [board [i ][j ]],pre + board [i ][j ], used , result )
60
+ backtrack (board ,i ,j + 1 ,trie [board [i ][j ]],pre + board [i ][j ], used , result )
61
+ backtrack (board ,i - 1 ,j ,trie [board [i ][j ]],pre + board [i ][j ], used , result )
62
+ backtrack (board ,i ,j - 1 ,trie [board [i ][j ]],pre + board [i ][j ], used , result )
49
63
used [i ][j ]= False
64
+
65
+ class MyTests (unittest .TestCase ):
66
+ def test_normal (self ):
67
+ board = [
68
+ ['o' ,'a' ,'a' ,'n' ],
69
+ ['e' ,'t' ,'a' ,'e' ],
70
+ ['i' ,'h' ,'k' ,'r' ],
71
+ ['i' ,'f' ,'l' ,'v' ]
72
+ ]
73
+
74
+ words = ["oath" ,"pea" ,"eat" ,"rain" ]
75
+ self .assertEqual (find_words (board , words ), ['oath' , 'eat' ])
76
+
77
+ def test_none (self ):
78
+ board = [
79
+ ['o' ,'a' ,'a' ,'n' ],
80
+ ['e' ,'t' ,'a' ,'e' ],
81
+ ['i' ,'h' ,'k' ,'r' ],
82
+ ['i' ,'f' ,'l' ,'v' ]
83
+ ]
84
+
85
+ words = ["chicken" , "nugget" , "hello" , "world" ]
86
+ self .assertEqual (find_words (board , words ), [])
87
+
88
+ def test_empty (self ):
89
+ board = []
90
+ words = []
91
+ self .assertEqual (find_words (board , words ), [])
92
+
93
+ def test_uneven (self ):
94
+ board = [
95
+ ['o' ,'a' ,'a' ,'n' ],
96
+ ['e' ,'t' ,'a' ,'e' ]
97
+ ]
98
+ words = ["oath" ,"pea" ,"eat" ,"rain" ]
99
+ self .assertEqual (find_words (board , words ), ['eat' ])
100
+
101
+ def test_repeat (self ):
102
+ board = [
103
+ ['a' ,'a' ,'a' ],
104
+ ['a' ,'a' ,'a' ],
105
+ ['a' ,'a' ,'a' ]
106
+ ]
107
+ words = ["a" , "aa" , "aaa" , "aaaa" , "aaaaa" ]
108
+ self .assertTrue (len (find_words (board , words ))== 5 )
109
+
110
+ if __name__ == "__main__" :
111
+ unittest .main ()
0 commit comments