题目-困难难度
给定一个 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”]
示例 2:
输入:board = [[“a”,“b”],[“c”,“d”]], words = [“abcb”]
输出:[]
提示:
- m == board.length
- n == board[i].length
- 1 <= m, n <= 12
- board[i][j] 是一个小写英文字母
- 1 <= words.length <= 3 * 104
- 1 <= words[i].length <= 10
- words[i] 由小写英文字母组成
- words 中的所有字符串互不相同
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/word-search-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
字典树
class TrieNode:
def __init__(self):
# 初始化 TrieNode。使用 defaultdict 创建一个名为 children 的字典,用于存储子节点
# 初始化一个名为 word 的字符串,用于存储到达当前节点所形成的单词
self.children = defaultdict(TrieNode)
self.word = ""
def insert(self, word):
# 向 Trie 中插入一个单词。从根节点开始,逐字符遍历单词
cur = self
for c in word:
cur = cur.children[c] # 对每个字符,移动到相应的子节点
cur.word = word # 在单词的最后一个字符对应的节点中存储整个单词
class Solution:
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
# 创建 TrieNode 实例并插入所有单词
t = TrieNode()
for word in words:
t.insert(word)
# 深度优先搜索函数
def dfs(now, x, y):
# 如果当前位置的字符不在 TrieNode 的子节点中,返回
if board[x][y] not in now.children:
return
ch = board[x][y] # 获取当前字符
c = now.children[ch] # 移动到 Trie 中相应的子节点
# 如果当前节点是一个单词的结尾,将该单词加入答案集合
if c.word != "":
ans.add(c.word)
# 标记当前位置为已访问
board[x][y] = "#"
# 对当前位置的上、下、左、右四个方向进行递归搜索
for i, j in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
if 0 <= i < m and 0 <= j < n:
dfs(c, i, j)
# 恢复当前位置的字符
board[x][y] = ch
ans = set() # 初始化答案集合
m, n = len(board), len(board[0]) # 获取字符板的行和列数
# 遍历字符板的每个位置
for i in range(m):
for j in range(n):
dfs(t, i, j) # 从每个位置开始深度优先搜索
return list(ans) # 返回找到的所有单词的列表