题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如[a b c e s f c s a d e e]是3*4矩阵,其包含字符串”bcced”的路径,但是矩阵中不包含“abcb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
解法一:非递归,用栈实现。
注意栈中Node的结构有个direction变量,表示上一次路径走过的方向。
struct Node
{
int i;
int j;
int direction;
Node(int x,int y,int di):i(x),j(y),direction(di){}
};
//回溯法使用栈模拟,非递归版本。
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
vector<vector<char>>m(rows,vector<char>(cols,' '));
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
m[i][j]=*matrix++;
}
}
vector<vector<bool>>visited(rows,vector<bool>(cols,false));
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
if(m[i][j]==*str){
str++;
if(*str=='\0') return true;//若出现"A",1,1,"A"这种情况防止没有在四方向寻找中得到true,而直接退出stack,在for外面中得到false
stack<Node> st;
Node curNode(i,j,-1);
st.push(curNode);
visited[i][j]=true;
while(!st.empty()){
Node& curNode=st.top();//reference
bool find=false;
int r,c;
while(curNode.direction<4&&find==false){
curNode.direction++;
switch(curNode.direction)
{
case 0:r=curNode.i-1;c=curNode.j;break;
case 1:r=curNode.i;c=curNode.j+1;break;
case 2:r=curNode.i+1;c=curNode.j;break;
case 3:r=curNode.i;c=curNode.j-1;break;
}
if(isValidPos(r,c,rows,cols)&&visited[r][c]==false){
if(m[r][c]==*str){
str++;
find=true;
Node newNode(r,c,-1);
st.push(newNode);
visited[r][c]=true;
}
if(*str=='\0')
return true;
}
}
if(find==false){
visited[curNode.i][curNode.j]=false;
st.pop();
str--;
}
}//while(!st.empty())
}//if(m[i][j]==*str)
}
}
return false;
}
bool isValidPos(int x,int y,int rows,int cols){
return (x>=0&&x<rows&&y>=0&&y<cols);
}
};
解法二:递归实现:
技巧:能用递归的就不用栈,否则就是自找麻烦!!!
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
bool*visited=new bool[rows*cols];
//memset(visited,0,sizeof(visited));
for(int i=0;i<rows*cols;++i) visited[i]=false;//这里果然不能用memset(visited,0,sizeof(visited))
int len=strlen(str);
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
if(helper(matrix,rows,cols,i,j,str,0,len,visited))
return true;
}
}
return false;
}
bool helper(char*matrix,int rows,int cols,int i,int j,char* str,int k,int len,bool*visited){
if(k==len) return true;
int index=i*cols+j;
if(i<0||i>=rows||j<0||j>=cols||visited[index]==true||matrix[index]!=str[k])
return false;
//if(k==len-1) return true;
visited[index]=true;
if( helper(matrix,rows,cols,i-1,j,str,k+1,len,visited)
||helper(matrix,rows,cols,i,j+1,str,k+1,len,visited)
||helper(matrix,rows,cols,i+1,j,str,k+1,len,visited)
||helper(matrix,rows,cols,i,j-1,str,k+1,len,visited)
){
return true;}
visited[index]=false;
return false;
}
};