0212-word-search-ii¶
Try it on leetcode
Description¶
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.
Example 1:

Input: board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"] Output: ["eat","oath"]
Example 2:

Input: board = [["a","b"],["c","d"]], words = ["abcb"] Output: []
Constraints:
m == board.length
n == board[i].length
1 <= m, n <= 12
board[i][j]
is a lowercase English letter.1 <= words.length <= 3 * 104
1 <= words[i].length <= 10
words[i]
consists of lowercase English letters.- All the strings of
words
are unique.
Solution(Python)¶
from collections import defaultdict
class TrieNode:
def __init__(self):
self.child = defaultdict(TrieNode)
self.end = False
class Trie:
def __init__(self):
self.root = TrieNode() # root Node
def insert(self, word):
node = self.root
for c in word:
node = node.child[c]
node.end = True
def search(self, word):
node = self.root
for c in ord:
node = node.children.get(c)
if not node:
return False
return node.end
class Solution:
# trie
# store words in trie
# run dfs to find the words
# Time Complexity: O(k*L+M*N*L)
# Space COmplexity: O(K*L+M*N)
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
# construct phase
result = []
trie = Trie()
rootNode = trie.root
for word in words:
trie.insert(word)
# search phase
n = len(board)
m = len(board[0])
for i in range(n):
for j in range(m):
# run dfs
self.dfs(board, rootNode, i, j, "", result)
return result
def dfs(self, board, node, i, j, path, result):
if node.end:
result.append(path)
node.end = False
# stopping condition
# out of boundary
# node doesn't exist
if i<0 or i>=len(board) or j < 0 or j >= len(board[0]):
return
currentCell = board[i][j] # using temparry cell to track by current cell value
node = node.child.get(currentCell)
if not node:
return
board[i][j] = "#" # visited cell
# adjacent check on four directions
self.dfs(board, node, i+1, j, path+currentCell, result)
self.dfs(board, node, i-1, j, path+currentCell, result)
self.dfs(board, node, i, j+1, path+currentCell, result)
self.dfs(board, node, i, j-1, path+currentCell, result)
# restore cell value
board[i][j] = currentCell