1.题目
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3乘4的矩阵中包含了一条字符串“bfce”的路径(路径中的字母用粗体标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
a b t g
c f c s
j d e h
2.笔者解答
第一反应是递归,和一个标记路径的数组,其它的貌似也没什么了,直接上代码。
int dr[4]={1,-1,0,0};
int dc[4]={0,0,1,-1};//方向向量
int road[m][n];
//m为二维矩阵的高,n为二维矩阵的宽,double_string[m][n]为原二维矩阵
int i,j;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
road[i][j]=0;//将路径数组初始标记为未走过,走过后,赋值为1
bool get_string(int depth,int aidstring_length,char *aidstring,int x,int y)
{
int i;
if(double_string[x][y].equals(aidstring[depth])
{
road[x][y]=1;
if(depth==length)
return true;
}
for(i=0;i<4;i++)
{
if(x+dr[i]>=0&&x+dr[i]<m&&y+dc[i]>=0&&y+dc[i]<n)
{
if(road[x+dr[i]][y+dc[i]]==0)
{
if(get_string(depth++,adistring_length,aidstring,x+dr[i],y+dc[i]))
return true;
}
}
}
}
3.就题论题
这是一个可以用回溯法解决的典型题。首先,在矩阵中任选中一个格子作为路径的起点。假设矩阵矩阵中某个格子的字符为ch,并且这个格子将对应于路径上的第i个字符不是ch,那么将这个格子不可能处在路径上的第i个位置。如果路径上的第i个字符正好是ch,那么到相邻的格子寻找路径上的第i+1个字符。除矩阵边界上的格子之外,其他格子都有四个相邻的格子。重复这个过程,直到路径上的所有字符都在矩阵中找到相应的位置。
由于回溯法的递归特性,路径可以被看成一个栈。当在矩阵中定位了路径中前n个字符的位置之后,在与第n个字符对应的格子的周围都没有找到第n+1个字符,这时候只好在路径上回到第n-1个字符,重新定位第n个字符。
由于路径不能重复进入矩阵的格子,所以还需要定义和字符矩阵大小一样的布尔值矩阵,用来标识路径是否已经进入了每个格子。下面的代码实现了这个回溯算法:
bool hasPath(char* matrix,int rows,int cols,char* str)
{
if(matrix==nullptr||rows<1||cols<1||str==nullptr)
return false;
bool *visited=new bool[row*cols];
memset(visited,0,rows*cols);
int pathLength=0;
for(int row=0;row<rows;++row)
{
for(int col=0;col<cols;++col)
{
if(hasPathCore(matrix,rows,cols,row,col,str,pathLength,visited))
{
return true;
}
}
}
delete[] visited;
return false;
}
bool haspathCore(const char* matrix,int rows,int cols,int row,int col,const char* str,int & pathLength,bool* visited)
{
if(str[pathLength]=='\0')
return true;
bool hasPath==false;
if(row>=0&&row<rows&&col>=0&&col<cols&&matrix[row*cols+col]==str[pathLength]&&!visited[row*cols+col])
{
++pathLength;
visited[row*cols+col]=true;
hasPath=hasPathCore(matrix,rows,cols,row,col-1,str,pathLength,visited)
||hasPathCore(matrix,rows,cols,row-1,col,str,pathLength,visited)
||hasPathCore(matrix,rows,cols,row,col+1,str,pathLength,visited)
||hasPathCore(matrix,rows,cols,row+1,col,str,pathLength,visited)
if(!hasPath)
{
--pathLength;
visited[row*cols+col]=false;
}
}
return hasPath;
}