leetcode 212. 单词搜索 II

给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。

示例:

输入: 
words = ["oath","pea","eat","rain"] and board =
[
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
]

输出: ["eat","oath"]
说明:
你可以假设所有输入都由小写字母 a-z 组成。

提示:

  • 你需要优化回溯算法以通过更大数据量的测试。你能否早点停止回溯?
  • 如果当前单词不存在于所有单词的前缀中,则可以立即停止回溯。什么样的数据结构可以有效地执行这样的操作?散列表是否可行?为什么? 前缀树如何?如果你想学习如何实现一个基本的前缀树,请先查看这个问题: 实现Trie(前缀树)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Solution:
def findWords(self, board, words):
"""
:type board: List[List[str]]
:type words: List[str]
:rtype: List[str]
"""
dictionary = {}
for i in words:
d = dictionary
for j in i:
if j not in d:
d[j] = {}
d = d[j]
d[1] = True
w = len(board[0])
h = len(board)
res = []
def dfs(i, j, d, prefix):
if 1 in d and prefix not in res:
res.append(prefix)
visited[i][j] = True
if i+1 < h:
if not visited[i+1][j] and board[i+1][j] in d:
dfs(i+1, j, d[board[i+1][j]], prefix+board[i+1][j])
visited[i+1][j] = False
if i-1 >= 0:
if not visited[i-1][j] and board[i-1][j] in d:
dfs(i-1, j, d[board[i-1][j]], prefix+board[i-1][j])
visited[i-1][j] = False
if j+1 < w:
if not visited[i][j+1] and board[i][j+1] in d:
dfs(i, j+1, d[board[i][j+1]], prefix+board[i][j+1])
visited[i][j+1] = False
if j-1 >= 0:
if not visited[i][j-1] and board[i][j-1] in d:
dfs(i, j-1, d[board[i][j-1]], prefix+board[i][j-1])
visited[i][j-1] = False

for i in range(h):
for j in range(w):
visited = [[False for j in range(w)] for i in range(h)]
if board[i][j] in dictionary:
dfs(i, j, dictionary[board[i][j]], board[i][j])

return res