请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
示例 1:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
示例 2:
输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false
提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
python代码如下所示:
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
for i in range(len(board)):
for j in range(len(board[0])):
if self.helper(i, j, board, word, 0) :
return True
return False
def helper(self,i, j, board, word, index):
if index == len(word):
return True
if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or word[index] != board[i][j] :
return False
board[i][j] = '#'
found = self.helper(i - 1, j, board, word, index + 1) \
or self.helper(i + 1, j, board, word, index + 1) \
or self.helper(i, j - 1, board, word, index + 1) \
or self.helper(i, j + 1, board, word, index + 1)
board[i][j] = word[index]
return found
第一眼看到这个代码,感觉很烦,直接就不想看了,仔细一看的话其实很简单,思路很清晰。
类中定义了两个函数,exist是主函数,helper是助手函数,先不看其中的具体细节和实现。直接告诉你说helper函数是用来发现从矩阵当前index为i、j的位置开始,是否存在目标字符串的路径。这样理解的话,主函数中用两层循环遍历矩阵,调用这个helper函数,就是把矩阵中每个位置的元素作为起点去检查是否存在目标字符串,如果以矩阵中一个元素为起点的目标字符串找到了,就直接返回真,若遍历结束还没找到,就返回false。
这样对主函数就有了一个清晰直观的认识,下面看一下helper函数的具体实现细节。
helper函数传入的参数意义分别是:行数、列数、源矩阵、目标字符串和字符串的索引。
第一个if:如果index等于len(word):,那说明字符串已经遍历结束了,说明在源矩阵中已经找到了目标字符串,返回真。
第二个if:如果i、j越界,并且当前位置的字符串值不等于源矩阵中对应位置的元素,说明这次搜索失败,返回false,主函数进行下一次搜索。
board[i][j] = ‘#’:代码运行到这个位置,说明当前位置是满足条件的,要继续搜索目标字符串的下一个值是否存在,需要拿矩阵上下左右的值与目标字符串下一个位置的值进行比较,也就有了下文的四个函数调用自身。但是,题目说了不允许往回搜索,就是说源矩阵中用过的元素就不能再用了,这时候需要把源矩阵中刚搜索的元素变成一个标记值,下一个位置搜索结束的时候再把它变回来,这样也就不破坏源矩阵的初始值。
讲到这里,本题目已经很清晰了。