一、题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
例如 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
关于 回溯法:
适合由多个步骤组成的问题,并且每个步骤都有多个选项;
所有的选项可以形象的用树状结构表示。
二、思路分析加代码实现
- 将一维数组转化为二维数组,并建立一个访问数组存储当前位置是否已经被访问
- 对于某个点而言,首先判断当前位置字符与所要寻找的字符是否相同,若相同,则继续寻找下一个;否则,回溯到上一步
- 关于寻找下一个位置:向上,向下,向左,向右。判断下一个位置是否超出边界,是否已被访问,是否与待查找元素相同。
public class Solution {
public boolean hasPath(char[] matrix, int rows, int cols, char[] str){
//将一维数组转换为二维数组
char[][] array=new char[rows][cols];
int k=0; //遍历一维数组的索引
for(int i=0;i<rows;++i){
for(int j=0;j<cols;++j){
array[i][j]=matrix[k++];
}
}
String s=new String(str);
for(int i=0;i<rows;++i){
for(int j=0;j<cols;++j){
boolean[][] Isvisited=new boolean[rows][cols];
if(subHasPath(array,i, j,s,Isvisited))
return true;
}
}
return false;
}
public static boolean subHasPath(char[][] matrix, int row, int col, String str, boolean[][] Isvisited){
if(matrix[row][col]!=str.charAt(0)) return false;
else if(str.length()==1) return true;
//将当前点设置为已访问
Isvisited[row][col]=true;
boolean flag=false;
if(IsBound(row-1,col,matrix)&&Isvisited[row-1][col]==false)
flag=flag||subHasPath(matrix,row-1, col, str.substring(1),Isvisited); //row-1,col
if(IsBound(row+1,col,matrix)&&Isvisited[row+1][col]==false)
flag=flag||subHasPath(matrix,row+1, col, str.substring(1),Isvisited); //row+1,col
if(IsBound(row,col-1,matrix)&&Isvisited[row][col-1]==false)
flag=flag||subHasPath(matrix,row, col-1, str.substring(1),Isvisited); //row,col-1
if(IsBound(row,col+1,matrix)&&Isvisited[row][col+1]==false)
flag=flag||subHasPath(matrix,row, col+1, str.substring(1),Isvisited); //row,col+
//若上面四种情况都不满足,则设置当前点为未访问
Isvisited[row][col]=false;
return flag;
}
//判断当前给定的行和列是否出界
public static boolean IsBound(int i,int j, char array[][]){
if(i>=0&&i<array.length&&j>=0&&j<array[0].length){
return true;
}
return false;
}
}