题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
思路:这是一道剑指offer上的题目,这是一道经典的回溯算法的题,然而我做的时候并没有想到回溯法,只是受到之前做的有关正则表达式匹配的算法的启发(我之前的博客有),大概的思路就是当前值的正确性与下一个值有关系,所以不仅要验证当前值是否正确,还要看下一个值是否也正确,所以就会产生类似如下的代码:
ans=curAns&&nextAns
这样的话很容易就想到了递归,想到了递归之后再在算法里面匹配各种情况,分析各个条件的正确性,也就能得出答案了。还有一点比较受启发的是善用与或逻辑表达式,能减少很多if else表达式。
下面是我的实现代码:
public class Solution {
char[][]m;
int rows,cols;
boolean[][] steps;//用来存放已走过的步
public boolean hasPath(char[] matrix, int rows, int cols, char[] str)
{
this.rows=rows;
this.cols=cols;
m=new char[rows+1][cols+1];
int index=0;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
m[i][j]=matrix[index++];
}
}
boolean ans=false;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
if(m[i][j]==str[0]){
steps=new boolean[rows][cols];
ans=searchM(0,str,i,j);
if(ans==true)
return ans;
}
}
}
return ans;
//从矩阵里把头找出来,逐个头匹配
}
boolean searchM(int index,char[] str,int row,int col){
//向上,向左,向右,向下探测,某一方向探测失败则往另一个方向探测,四个方向都探测失败,则失败
//探测过程注意矩阵不要越界
if(steps[row][col])//已经走过了
return false;
// if(index==str.length)//前面的都匹配成功了
// return true;//看是否匹配到了最后一个
steps[row][col]=true;//走过
boolean ans,curMatch=false;
if(m[row][col]==str[index])
curMatch=true;
//当前匹配或者四个方向下一个字符匹配
boolean up,down,left,right;
//当前匹配才继续判断下一个是否合适
//里面是判断能否往下一步走的条件,当到最后一个不能再往下一步走了,就看他是否是最后一个
up=curMatch&&((index+1<str.length&&row-1>=0&&!steps[row-1][col]&&searchM(index+1,str,row-1,col))||index==str.length-1);//从哪个方向来,所以应该相反,从上面来,就是不用再往上走了
down=curMatch&&((index+1<str.length&&row+1<rows&&!steps[row+1][col]&&searchM(index+1,str,row+1,col))||index==str.length-1);
left=curMatch&&((index+1<str.length&&col-1>=0&&!steps[row][col-1]&&searchM(index+1,str,row,col-1))||index==str.length-1);
right=curMatch&&((index+1<str.length&&col+1<cols&&!steps[row][col+1]&&searchM(index+1,str,row,col+1))||index==str.length-1);
ans=(up||down||left||right);//有一个方向正确即可
if(ans==false)//该点不正确,当没走过
steps[row][col]=false;
return ans;
}
}