dfs 解决(隐式)图搜索问题
132. 单词搜索 II
中文
English
给出一个由小写字母组成的矩阵和一个字典。找出所有同时在字典和矩阵中出现的单词。一个单词可以从矩阵中的任意位置开始,可以向左/右/上/下四个相邻方向移动。一个字母在一个单词中只能被使用一次。且字典中不存在重复单词
样例
样例 1:
输入:["doaf","agai","dcan"],["dog","dad","dgdg","can","again"]
输出:["again","can","dad","dog"]
解释:
d o a f
a g a i
d c a n
矩阵中查找,返回 ["again","can","dad","dog"]。
样例 2:
输入:["a"],["b"]
输出:[]
解释:
a
矩阵中查找,返回 []。
挑战
使用单词查找树来实现你的算法
DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]
class Solution:
"""
@param board: A list of lists of character
@param words: A list of string
@return: A list of string
"""
def wordSearchII(self, board, words):
if board is None or len(board) == 0:
return []
word_set = set(words)
prefix_set = set()
for word in words:
for i in range(len(word)):
prefix_set.add(word[:i + 1])
result = set()
for i in range(len(board)):
for j in range(len(board[0])):
c = board[i][j]
self.search(
board,
i,
j,
board[i][j],
word_set,
prefix_set,
set([(i, j)]),
result,
)
return list(result)
def search(self, board, x, y, word, word_set, prefix_set, visited, result):
if word not in prefix_set:
return
if word in word_set:
result.add(word)
for delta_x, delta_y in DIRECTIONS:
x_ = x + delta_x
y_ = y + delta_y
if not self.inside(board, x_, y_):
continue
if (x_, y_) in visited:
continue
visited.add((x_, y_))
self.search(
board,
x_,
y_,
word + board[x_][y_],
word_set,
prefix_set,
visited,
result,
)
visited.remove((x_, y_))
def inside(self, board, x, y):
return 0 <= x < len(board) and 0 <= y < len(board[0])
注意使用prefix hash map来剪枝。
使用trie的解法:
DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]
class TrieNode: #定义字典树的节点
def __init__(self):
self.children = {}
self.is_word = False
self.word = None
class Trie:
def __init__(self):
self.root = TrieNode()
def add(self, word): #字典树插入单词
node = self.root
for c in word:
if c not in node.children:
node.children[c] = TrieNode() #在此节点申请节点
node = node.children[c] #继续遍历
node.is_word = True
node.word = word #存入单词
def find(self, word):
node = self.root
for c in word:
node = node.children.get(c)
if node is None:
return None
return node
class Solution:
"""
@param board: A list of lists of character
@param words: A list of string
@return: A list of string
"""
def wordSearchII(self, board, words):
if board is None or len(board) == 0:
return []
trie = Trie()
for word in words: #插入单词
trie.add(word)
result = set()
for i in range(len(board)): #遍历字母矩阵,将每个字母作为单词首字母开始搜索
for j in range(len(board[0])):
c = board[i][j]
self.search(
board,
i,
j,
trie.root.children.get(c),
set([(i, j)]),
result,
)
return list(result)
def search(self, board, x, y, node, visited, result): #在字典树上dfs查找
if node is None:
return
if node.is_word:
result.add(node.word)
for delta_x, delta_y in DIRECTIONS: #向四个方向查找
x_ = x + delta_x
y_ = y + delta_y
if not self.inside(board, x_, y_):
continue
if (x_, y_) in visited:
continue
visited.add((x_, y_))
self.search(
board,
x_,
y_,
node.children.get(board[x_][y_]),
visited,
result,
)
visited.remove((x_, y_))
def inside(self, board, x, y):
return 0 <= x < len(board) and 0 <= y < len(board[0])

浙公网安备 33010602011771号