Description
Given a 2D board and a list of words from the dictionary, find all words in the board.
Each word must 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 in a word.
Example:
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"]
Note:
- All inputs are consist of lowercase letters
a-z
. - The values of
words
are distinct.
Solutions
1. DFS
用 DFS TLE 了……
class Solution:
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
if not board:
return []
res = []
for word in words:
if self.exist(board, word):
res.append(word)
return res
def exist(self, board: List[List[str]], word: str) -> bool:
if not board:
return False
r, c = len(board), len(board[0])
for i in range(r):
for j in range(c):
if self.dfs(board, word, i, j, r, c):
return True
return False
def dfs(self, board, word, i, j, r, c):
if not word:
return True
if not (0 <= i < r) or not (0 <= j < c) or word[0] != board[i][j]:
return False
tmp = board[i][j]
board[i][j] = '#'
res = self.dfs(board, word[1:], i + 1, j, r, c) or \
self.dfs(board, word[1:], i - 1, j, r, c) or \
self.dfs(board, word[1:], i, j + 1, r, c) or \
self.dfs(board, word[1:], i, j - 1, r, c)
board[i][j] = tmp
return res
# Time Limit Exceeded
2. Trie
class TrieNode():
def __init__(self):
self.children = collections.defaultdict(TrieNode)
self.isWord = False
class Trie():
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for w in word:
node = node.children[w]
node.isWord = True
def search(self, word):
node = self.root
for w in word:
node = node.children.get(w)
if not node:
return False
return node.isWord
class Solution(object):
def findWords(self, board, words):
"""
:type board: List[List[str]]
:type words: List[str]
:rtype: List[str]
"""
if not board or len(board) < 1:
return []
res = []
trie = Trie()
node = trie.root
self.r, self.c = len(board), len(board[0])
for word in words:
trie.insert(word)
for i in range(self.r):
for j in range(self.c):
self.dfs(board, node, '', i, j, res)
return res
def dfs(self, board, node, path, row, col, res):
if node.isWord:
res.append(path)
node.isWord = False
if row < 0 or row >= self.r or col < 0 or col >= self.c:
return
# Avoid access the same character
char = board[row][col]
node = node.children.get(char)
if not node:
return
board[row][col] = '#'
self.dfs(board, node, path+char, row, col+1, res)
self.dfs(board, node, path+char, row, col-1, res)
self.dfs(board, node, path+char, row+1, col, res)
self.dfs(board, node, path+char, row-1, col, res)
board[row][col] = char
# Runtime: 488 ms, faster than 25.75% of Python online submissions for Word Search II.
# Memory Usage: 47.9 MB, less than 34.78% of Python online submissions for Word Search II.