题目描述:
请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如:
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
数据范围:0<=n,m<=20,1 <=len <=25,
进阶:时间复杂度O(n^2),空间复杂度O(n^2)
示例1:
输入:[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcced"
返回值:true
示例2:
输入:[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcb"
扫描二维码关注公众号,回复: 13289009 查看本文章返回值:false
解题思路:
对于matrix数组,从 matrix[0][0 ]的位置遍历数组。对于 matrix 中任一位置处的元素 matrix[i][j] 而言,从该元素的上左下右四个位置分别进行查找,判断该位置的元素是否合法。这里的合法包括两部分:
(1)由该位置出发进行的查找,新的位置不能越界。
(2)新位置的字符必须和 word 的对应位置字符匹配。
在查找过程中,如果当前位置匹配,则进行按照上左下右的方向进行查找,并对当前位置做以标记。如果不匹配,则撤销标记,恢复原值。
代码如下:
import java.util.*;
public class Solution {
public boolean hasPath (char[][] matrix, String word) {
//将字符串转为字符数组
char[] ch = word.toCharArray();
//遍历矩阵
for(int i=0; i < matrix.length; i++){
for(int j=0; j < matrix[0].length; j++){
//以当前元素为起始点,检查是否存在符合条件的路径
if(dfs(matrix, i, j, 0, ch)){
return true;
}
}
}
return false;
}
//参数说明:矩阵,行,列,匹配位置,字符数组
public boolean dfs(char[][] matrix, int i, int j, int k, char[] ch){
//处理边界条件,包括:行越界,列越界,矩阵元素被访问过
if(i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || ch[k] != matrix[i][j]){
return false;
}
//表示前面k-1字符都已经匹配成功,并且最后一个字符也匹配成功,直接返回true
if(k == ch.length-1){
return true;
}
//标记当前矩阵元素,将其修改为#,表示此元素已经被访问过。
matrix[i][j] = '#';
//对当前元素的上左下右位置进行检查
boolean ret = dfs(matrix, i, j-1, k+1, ch) || dfs(matrix, i-1, j, k+1, ch) || dfs(matrix, i, j+1, k+1, ch) || dfs(matrix, i+1, j, k+1, ch);
//回退时还原矩阵中的元素
matrix[i][j] = ch[k];
return ret;
}
}
总结:对于这种二维数组的题目,包括走迷宫等等类似的题目,其解题过程一般分为以下几步:
- 数组中方向的表示:利用位置的偏移模拟每一次方向的移动,本题中就是从上左下右的方向进行移动
- 现场恢复:当前搜索状态不满足要求回溯时,应该还原数组状态。