首页 > 试题广场 >

矩阵中的路径

[编程题]矩阵中的路径
  • 热度指数:81850 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
数据范围:,
示例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"

输出

false
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;
}

发表于 2023-05-29 01:01:47 回复(0)
c语言的非递归写法,自己写的代码,肯定还有优化的地方请批评指正
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;
}

发表于 2022-01-29 17:03:43 回复(0)

问题信息

dfs
上传者:牛客301499号
难度:
2条回答 3103浏览

热门推荐

通过挑战的用户

查看代码