题目来自牛客网剑指offer专题:链接
题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。例如下图的矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
解题思路
因为要找出一条路径,使得路径按顺序经过的字符刚好可以组成给出的字符串,因此很容易想到使用回溯法,暴力dfs出满足条件的路径。
具体思路是用一个全初始化为0的二维矩阵arr记录每个位置是否经过,然后从矩阵matrix的每一个位置出发做dfs,每次dfs都要考虑上下左右四个方向,不越界才进行递归搜索,走了一个新的格子之后要将arr中该格子所处位置的值置为1,递归结束的条件为找到包含该字符串的完整路径或当前所处格子的字符与字符串对应位置的字符不同。
最后回到上一层递归中接收答案,如果有解就返回true,无解返回false。
AC代码
运行时间:5ms
占用内存:504k
class Solution {
public:
char *m;
char *s;
int row;
int col;
bool hasPath(char* matrix, int rows, int cols, char* str)
{
m=matrix;
s=str;
row=rows;
col=cols;
vector<vector<int> > arr(rows); //记录是否经过该位置
for(auto &i:arr)
i.resize(cols,0);
for(int i=0;i<arr.size();i++)
for(int j=0;j<arr[0].size();j++){
if(getans(arr,0,i,j))
return true;
}
return false;
}
bool getans(vector<vector<int> > arr,int nowpos,int x,int y){
bool ans1,ans2,ans3,ans4;
ans1=ans2=ans3=ans4=false;
arr[x][y]=1;
if(m[x*col+y]==s[nowpos]&&nowpos==strlen(s)-1) //找到字符串对应的路径
return true;
if(m[x*col+y]!=s[nowpos]) //当前格子的字符和字符串中对应位置的字符不同
return false;
if(y>=1&&!arr[x][y-1]) //左
ans1=getans(arr,nowpos+1,x,y-1);
if(y<col-1&&!arr[x][y+1]) //右
ans2=getans(arr,nowpos+1,x,y+1);
if(x>=1&&!arr[x-1][y]) //上
ans3=getans(arr,nowpos+1,x-1,y);
if(x<row-1&&!arr[x+1][y]) //下
ans4=getans(arr,nowpos+1,x+1,y);
if(ans1||ans2||ans3||ans4)
return true;
return false;
}
};