Given anĀ m x nĀ boardĀ of characters and a list of stringsĀ words, returnĀ all words on the board.
Each word must be constructed from letters of sequentially adjacent cells, whereĀ adjacent cellsĀ are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
solution
We create a trie to store the list of words that weāre trying to search for. Then, for each cell in the matrix, if it is the start of a word, we BFS starting from it to try to find a matching word.
class TrieNode:
def __init__(self, val, isEnd = False):
self.val = val
self.children = {}
self.isEnd = isEnd
class Trie:
def __init__(self):
self.root = TrieNode(None)
def insert(self, word):
cur = self.root
for char in word:
if char in cur.children:
cur = cur.children[char]
else:
new = TrieNode(char)
cur.children[char] = new
cur = new
# cur is on the last character of the word
cur.isEnd = Truedef findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
trie = Trie()
# construct trie from dictionary
for word in words:
trie.insert(word)
ans = []
dirs = [[0,1],[1,0],[0,-1],[-1,0]]
visited = set()
def dfs(x, y, trieNode, acc):
if trieNode.isEnd:
ans.append(acc)
trieNode.isEnd = False # avoid dupes
for d in dirs:
nx, ny = x+d[0], y+d[1]
if nx >= 0 and nx < len(board) and ny >= 0 and ny < len(board[0]):
if (nx, ny) not in visited:
next_char = board[nx][ny]
if next_char in trieNode.children:
visited.add((nx,ny))
dfs(nx, ny, trieNode.children[next_char], acc+next_char)
visited.remove((nx,ny))
for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j] in trie.root.children:
visited.add((i,j))
dfs(i, j, trie.root.children[board[i][j]], board[i][j])
visited.remove((i,j))
return ans