题目:
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
思路:题目配上图片,首先要理解题意,题目是想让我们根据word中的字符顺序,在矩阵中找到连续的字符集合,并且上一个字符和下一个字符只能是相邻的,不能是在word中相邻的两个字符在矩阵中却不相邻。
题目的做法可以考虑使用DFS深度遍历,即照着一条路径直接搜索到最下面,直到这条路径不通了,说明不是这条路,然后再回溯回去,重新从上一个元素节点找路,如果也找不到,那说明这个节点的四个方向的路径都不可以,同样回溯回去。具体的备注在代码里面
错误跳出条件:越界或者是和要找的元素不相等。
代码结束递归条件:n=word的长度-1
代码:
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
#通过深度遍历还有回溯来查找相连的字符,直到全部找完
#递归的参数是元素在矩阵中的位置和在单词word中的索引
def dfs(i,j,n):
#三种情况会跳出递归返回flse,不相等,索引越界都会返回false
if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[n]: return False
if n==len(word)-1:return True#如果索引n通过每次加一已经等于单词的长度了,那就直接返回True
#下面的情况是矩阵中的元素是word索引要的元素
#首先将元素置空,省去了深度遍历中的判断是否已经遍历过这一步,
#这样做是为了避免下一个元素通过下右上左的顺序来遍历的时候重复
board[i][j]=""
#引入res表示遍历的状态,上下左右四个方向用四个dfs递归来做,
#遍历出来一个符合条件就可以执行下面,所以用or来组合
res=dfs(i+1,j,n+1) or dfs(i,j+1,n+1) or dfs(i-1,j,n+1) or dfs(i,j-1,n+1)
#上面将当前的元素置空,下面还要把元素的值变成原来的样子,避免四个方向都找不到值需要
#回溯的时候,那时候ij值就变化了,还可能再访问到这个元素,也就是说矩阵中的一个元素是
#可以被多条路径遍历好几次的,这条路不通那我就要回去,回去的时候这个当前元素的值不能
#有变化
board[i][j]=word[n]
return res#res中放着当前遍历结果的状态
for i in range(len(board)):
for j in range(len(board[0])):
if dfs(i,j,0):return True#开始递归,深度遍历
return False