请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。
路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。
如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。
例如: a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,
因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
回溯法:
- 我们需要定义一个和矩阵相同大小的boolean数组,用来记录每个格子的访问记录
- 定义一个int类型的pathLength,用来记录每一次递归中匹配到的长度
- 这个时候我们需要遍历每一个格子,对每个格子进行递归查找路径
- 如果查找到了路径,停止循环遍历;遍历完后,都没有找到,说明不存在路径
- 在我们的递归函数中,首先需要设置递归的终止条件
- 越界、格子被访问过、该格子的值和相应位置上的字符串不相等,都是没有找到,需要返回false,停止递归
- 匹配到了一个相同的长度,说明找到了路径,返回true,停止递归
- 如果上面都没有遇见,说明需要进行下一次的递归,并且把该格子标记为true,代表访问过
- 如果在下一层的递归中没有找到路径,说明这个格子在这条路径上失败了,可以把该格子重新标记为false
- 进行回溯,回到上一个格子,继续递归,一次类推
public class MatrixPath {
public static boolean matrixPath(int rows,int cols,char[] matrix,char[] str){
//设置一个Boolean数组标记一个格子是否被访问过
boolean[] isVisited = new boolean[rows*cols];
for(int i = 0;i < rows*cols;i++){
isVisited[i] = false;
}
//匹配到的长度
int pathLength = 0;
//遍历每个格子,从每个格子都各自出发
for(int row = 0;row < rows;row++){
for(int col = 0;col < cols;col++){
if(matrixPath(rows,cols,row,col,matrix,str,isVisited,pathLength+1)){
return true;
}
}
}
return false;
}
private static boolean matrixPath(int rows,int cols,int row,int col,char[] matrix,char[] str,boolean[] isVisited,int pathLength){
//越界、格子被访问过、该格子的值和相应位置上的字符串不相等,都是没有找到,需要返回false
if(row < 0 || row >= rows || col < 0 || col >= cols
|| isVisited[row*cols+col] || matrix[row*cols+col] != str[pathLength]){
return false;
}
//匹配到了一个合适的长度,说明找到了,返回true
if(pathLength == str.length - 1){
return true;
}
//标记该格子被访问过
isVisited[row*cols+col] = true;
//从这个格子出发四处发散寻找路径
boolean hasPath = matrixPath(rows,cols,row,col+1,matrix,str,isVisited,pathLength+1)||
matrixPath(rows,cols,row,col-1,matrix,str,isVisited,pathLength+1)||
matrixPath(rows,cols,row+1,col,matrix,str,isVisited,pathLength+1)||
matrixPath(rows,cols,row-1,col,matrix,str,isVisited,pathLength+1);
//没找到路径,把该格子标记为未被访问过
if(!hasPath){
isVisited[row*cols+col]=false;
}
//返回该格子是否有路径
return hasPath;
}
//test
public static void main(String[] args){
char[] matrix = {'a','b', 'c', 'e', 's', 'f', 'c', 's', 'a', 'd', 'e', 'e'};
char[] str = {'b','c','c','e','d'};
System.out.println(matrixPath(3,4,matrix,str));
}
}