题目描述

请设计⼀个函数,⽤来判断在⼀个矩阵中是否存在⼀条包含某字符串所有字符的路径。路径可以从矩阵中的任意⼀个格⼦开始,每⼀步可以在矩阵中向左,向右,向上,向下移动⼀个格⼦。如果⼀条路径经过了矩阵中的某⼀个格⼦,则该路径不能再进⼊该格⼦。 例如矩阵: 中包含⼀条字符串 " bcced " 的路径,但是矩阵中不包含 " abcb " 路径,因为字符串的第⼀个字符 b占据了矩阵中的第⼀⾏第⼆个格⼦之后,路径不能再次进⼊该格⼦。

示例1

输⼊:[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcced" 返回值:true

思路及解答

DFS回溯

主要的思路是对于每⼀个字符为起点,递归向四周拓展,然后遇到不匹配返回 false,匹配则接着匹配直到完成,⾥⾯包含了 回溯 的思想。步骤如下:

针对每⼀个字符为起点,初始化⼀个和矩阵⼀样⼤⼩的标识数组,标识该位置是否被访问过,⼀开始默认是false 。

  1. 如果当前的字符索引已经超过了字符串⻓度,说明前⾯已经完全匹配成功,直接返回 true

  2. 如果⾏索引和列索引,不在有效的范围内,或者改位置已经标识被访问,直接返回 false

  3. 否则将当前标识置为已经访问过

  4. 如果矩阵当前位置的字符和字符串相等,那么就字符串的索引加⼀,递归判断周边的四个,只要⼀个的结果为 true,就返回 true,否则将该位置置为没有访问过(相当于回溯,退回上⼀步),返回 false 。矩阵当前位置的字符和字符串不相等,否则同样也是将该位置置为没有访问过(相当于回溯,退回上⼀步),返回 false 。

  • 时间复杂度:O(3^k × m × n),其中k为单词长度,m、n为矩阵尺寸。每个点有3个方向可选(不能回退)

  • 空间复杂度:O(k),递归栈深度和visited数组空间

原地标记优化(最优)

通过修改原矩阵来标记访问状态,节省空间。 关键技巧:

  1. 临时修改:将访问过的board[i][j]改为'#'(或其他不在字母表中的字符)

  2. 自动避障:后续搜索遇到'#'会因字符不匹配而自动跳过

  3. 状态恢复:回溯时恢复原始字符,确保不影响其他路径搜索

算法分析:

  • 时间复杂度:O(3^k × m × n),与前述方法相同

  • 空间复杂度:O(1),显著优化!仅使用常数空间(递归栈空间不可避免)