给出一个由小写字母组成的矩阵和一个字典。找出所有同时在字典和矩阵中出现的单词。一个单词可以从矩阵中的任意位置开始,可以向左/右/上/下四个相邻方向移动。一个字母在一个单词中只能被使用一次。且字典中不存在重复单词。
tip:构建字典树/前缀集合,用于在dfs过程中,如果path上的字母不是一个单词的前缀及时停止搜索。
1 class TrieNode: 2 3 def __init__(self): 4 self.children, self.word = {}, None 5 6 class Trie: 7 8 def __init__(self): 9 self.root = TrieNode() 10 11 def add(self, word): 12 cur_node = self.root 13 for char in word: 14 if char not in cur_node.children: 15 cur_node.children[char] = TrieNode() 16 cur_node = cur_node.children[char] 17 cur_node.word = word 18 19 class Solution: 20 """ 21 @param board: A list of lists of character 22 @param words: A list of string 23 @return: A list of string 24 """ 25 def findWords(self, board: List[List[str]], words: List[str]) -> List[str]: 26 # write your code here 27 if board is None or len(board) == 0 or len(board[0]) == 0: 28 return [] 29 ans = set() 30 trie = Trie() 31 for word in words: 32 trie.add(word) 33 for i in range(len(board)): 34 for j in range(len(board[0])): 35 self.dfs(board, i, j, trie.root, ans) 36 return list(ans) 37 38 def dfs(self, board, i, j, cur_node, ans): 39 40 if board[i][j] not in cur_node.children: 41 return 42 43 next_node = cur_node.children[board[i][j]] 44 45 if next_node.word is not None: 46 ans.add(next_node.word) 47 48 DIR = [(1, 0), (-1, 0), (0, 1), (0, -1)] 49 50 original = board[i][j] 51 board[i][j] = '#' 52 53 for (di, dj) in DIR: 54 next_i, next_j = i + di, j + dj 55 if next_i < 0 or next_i >= len(board) or next_j < 0 or next_j >= len(board[0]): 56 continue 57 if board[next_i][next_j] == '#': 58 continue 59 self.dfs(board, next_i, next_j, next_node, ans) 60 61 board[i][j] = original 62