请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
数据范围:
,
[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcced"
true
[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcb"
false
0 <= matrix.length <= 2000 <= matrix[i].length <= 200
int flag = 0;
int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
bool dfs(char** matrix,int x,int y,char* word,int row,int col)
{
if(*word == '\0')
flag = 1;
for(int i=0;i<4;i++)
{
int tx = x+next[i][0];
int ty = y+next[i][1];
if(tx<0 || tx>=row || ty <0 || ty >=col)
continue;
if(matrix[tx][ty] != '.' && matrix[tx][ty] == *word)
{
char c = matrix[tx][ty];
matrix[tx][ty] = '.';
dfs(matrix,tx,ty,word+1,row,col);
matrix[tx][ty] = c;
}
}
if(flag == 1)
return true;
return false;
}
bool hasPath(char** matrix, int matrixRowLen, int* matrixColLen, char* word )
{
// write code here
int len = strlen(word);
for(int i =0;i<matrixRowLen;i++)
{
for(int j =0;j<*matrixColLen;j++)
{
if(matrix[i][j] == word[0])
{
char c = matrix[i][j];
matrix[i][j] = '.';
if(dfs(matrix,i,j,word+1,matrixRowLen,*matrixColLen))
return true;
matrix[i][j] = c;
}
}
}
return false;
} int hasPath(char** matrix, int matrixRowLen, int* matrixColLen, char* word ) {
//创建一个辅助数组,并初始化
int have[matrixRowLen][*matrixColLen];
//用一个visit数组记录行为 先上后下再左最后向右
int visit[25];
for(int i=0;i<matrixRowLen;i++){
for(int j=0;j<(*matrixColLen);j++){
//当第一个字符匹配时
int p=0; //这个是用于访问字符串的计数器
if(matrix[i][j]==word[p]){ //如果该元素与字符串第一个元素相同则开始找元素
//将记录数组清零和动作的数组清零
memset(visit,0,sizeof(visit));
memset(have,0,sizeof(have));
//下标,i1和j1即为当前位置
int i1=i,j1=j;
//将此处做标记,第一个数字自动标记
have[i1][j1]=1;
//循环结束的标志是p计数器小于0或者已经访问到了字符串末尾
while(p>=0&&word[p]!='\0'){
//看当前visit[p]动作数组的值
switch(visit[p]){
case 0:if(i1-1>=0&&have[i1-1][j1]==0&&word[p+1]==matrix[i1-1][j1]) {
have[i1--][j1]=1;//向上走了
visit[p]=1; //最后一次访问p执行的是向上转操作
p++; break;
}
case 1:if(i1+1<matrixRowLen&&have[i1+1][j1]==0&&word[p+1]==matrix[i1+1][j1]) {
have[i1++][j1]=1;//向下转了
visit[p]=2; //最后一次访问p执行的是向下转转操作
p++; break;
}
//向上判断边界是否为0
case 2:if(j1-1>=0&&have[i1][j1-1]==0&&word[p+1]==matrix[i1][j1-1]) {
have[i1][j1--]=1;//向左
visit[p]=3; //最后一次访问p执行的是向左走操作
p++; break;
}
case 3:if(j1+1<(* matrixColLen)&&have[i1][j1+1]==0&&word[p+1]==matrix[i1][j1+1]) {
have[i1][j1++]=1;//向右
visit[p]=4; //最后一次访问p执行的是向右走操作
p++; break;
}
//如果不匹配那么 看是否已经访问完了字符串
default:{
//如果访问完了字符串,那么直接return
if(word[p+1]=='\0') return 1; //如果访问到了数组末尾则返回正确
else{
//否则就要进行回溯
//那么此时的元素被标记为未访问
have[i1][j1]=0;
//如果此时的元素是第一个元素
if(p<=0){
p--;
break;
}
else{
//检查上一次数组的动作,根据上一次的动作来修改下标
switch(visit[--p]){
case 1: i1++;break;
case 2: i1--;break;
case 3: j1++;break;
case 4: j1--;break;
}
}
}
}
}
}
}
}
}
return 0;
}