题目描述
➡ 题目链接 ⬅
给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例1:
输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]
解题思路
- 构建字典树
Trie
,将words中的词全部插入到Trie
中。 - 深度优先搜索,遍历
board
,搜索Trie
。
代码
class Solution:
def findWords(self, board, words):
trie = {}
for c in words:
tree = trie
for i in c:
tree = tree.setdefault(i, {})
tree['#'] = '#'
res = set()
m, n = len(board), len(board[0])
def dfs(i, j, prev, tree, seen):
if '#' in tree:
res.add(prev)
for di, dj in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
new_i, new_j = i+di, j+dj
if 0 <= new_i < m and 0 <= new_j < n and (new_i, new_j) not in seen and board[new_i][new_j] in tree:
dfs(new_i, new_j, prev+board[new_i][new_j], tree[board[new_i][new_j]], seen|{(new_i, new_j)})
for i in range(m):
for j in range(n):
if board[i][j] in trie:
dfs(i, j, board[i][j], trie[board[i][j]], {(i, j)})
return list(res)
时间复杂度分析
假设m
, n
分别是board
的行数和列数,L
为单词的最大长度,则时间复杂度为O(m×n×4×(3^(L-1)))
其中,m*n
是两层for循环的时间复杂度,4×3^(L-1)
是dfs的时间复杂度,最初(第一步)有四个方向可以搜索(最坏情况),但在接下来的搜索中,只有三个方向可以搜索(不包括从上一步来的方向),即4×3^(L-1)