题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
代码实现如下:
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
if(matrix==nullptr || rows < 1 || cols < 1 || str==nullptr)
return false;
vector<int> visted(rows*cols,0);
//矩阵图中同一个字符可能有多次出现,所以要找不同的起点
for(int row=0;row<rows;row++){
for(int col=0;col<cols;col++){
if(findPath(matrix,str,rows,cols,row,col,visted,0))
return true;
}
}
return false;
}
bool findPath(char *matrix,const char *str,int rows,int cols,int row,int col,vector<int> &visted,int k){
if(str[k] == '\0')//找到完整字符串,结束条件
return true;
int index = row*cols+col;
if(row<0 || row>=rows || col<0 || col>=cols || str[k]!=matrix[index] || visted[index]==1)
return false;
visted[index] = 1;
//回溯,递归寻找,每次找到了就给k加一,找不到,还原
if(findPath(matrix,str,rows,cols,row,col-1,visted,k+1)
|| findPath(matrix,str,rows,cols,row,col+1,visted,k+1)
|| findPath(matrix,str,rows,cols,row-1,col,visted,k+1)
|| findPath(matrix,str,rows,cols,row+1,col,visted,k+1)){
return true;
}
visted[index] = 0;
return false;
}
};
完整程序代码:
#include<iostream>
#include<string.h>
using namespace std;
void show(char *matrix,int rows,int cols);
bool havePath(char *matrix,const char *str,int rows,int cols);
bool findPath(char *matrix,const char *str,int rows,int cols,int row,int col,bool *visted,int &stepLen);
void test1();
void test2();
void test3();
void test4();
int main(){
char matrix[] = "abtgcfcsjdeh";
const char *str = "bfce";
cout<<"径阵路径如下:"<<endl;
show(matrix,3,4);
cout<<endl;
bool haspath = havePath(matrix,str,3,4);
cout<<str<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
test1();
test2();
test3();//只有一行
test4();//空矩阵
return 0;
}
void test2(){
char matrix[] = "ABTGCFCSJDEH";
const char *str = "ABFB";
cout<<"径阵路径如下:"<<endl;
show(matrix,3,4);
cout<<endl;
bool haspath = havePath(matrix,str,3,4);
cout<<str<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
}
void test1(){
char matrix1[] = "ABCESFCSADEE";
const char *str1 = "SEE";
cout<<"径阵路径如下:"<<endl;
show(matrix1,3,4);
cout<<endl;
bool haspath = havePath(matrix1,str1,3,4);
cout<<str1<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
}
void test3(){
char matrix1[] = "ABCE";
const char *str1 = "SEE";
cout<<"径阵路径如下:"<<endl;
show(matrix1,1,4);
cout<<endl;
bool haspath = havePath(matrix1,str1,3,4);
cout<<str1<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
}
void test4(){
char *matrix1 = nullptr;
const char *str1 = "SEE";
cout<<"径阵路径如下:"<<endl;
show(matrix1,1,4);
cout<<endl;
bool haspath = havePath(matrix1,str1,3,4);
cout<<str1<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
}
bool havePath(char *matrix,const char *str,int rows,int cols){
if(matrix == nullptr || rows < 0 || cols < 0)
return false;
//string.h 或 memory.h
bool *visted = new bool[rows * cols];
memset(visted,0,sizeof(visted));//全部置为0,即false
bool haspath = false;
int stepLen = 0;
//矩阵图中同一个字符可能有多次出现,所以要找不同的起点
for(int row=0;row<rows;row++){
for(int col=0;col<cols;col++){
haspath = findPath(matrix,str,rows,cols,row,col,visted,stepLen);
if(haspath == true)
return true;
}
}
delete []visted;
return false;
}
bool findPath(char *matrix,const char *str,int rows,int cols,int row,int col,bool *visted,int &stepLen){
if(matrix == nullptr || str == nullptr)
return false;
if(rows < 1 || cols < 1 || row < 0 || row >= rows || col < 0 || col >= cols)
return false;
if(str[stepLen] == '\0')//找到完整字符串,结束条件
return true;
bool isFind = false;
if( (str[stepLen] == matrix[row * cols + col]) && (visted[row * cols + col] == false) )
{
visted[row * cols + col] = true;
stepLen++;
isFind = findPath(matrix,str,rows,cols,row,col-1,visted,stepLen)//左
|| findPath(matrix,str,rows,cols,row,col+1,visted,stepLen)
|| findPath(matrix,str,rows,cols,row-1,col,visted,stepLen)
|| findPath(matrix,str,rows,cols,row+1,col,visted,stepLen);
//注意这个步数回朔只能放在if内,而不能放在上面的if外
//因为只有在这个if内stepLen才会++,所以这里才能回朔--
if(isFind == false){
stepLen--;
visted[row * cols + col] = false;
}
}
return isFind;
}
void show(char *matrix,int rows,int cols){
if(matrix == nullptr)
return;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
cout<<matrix[i*cols+j]<<" ";
}
cout<<endl;
}
}
void show(char *matrix,int rows,int cols);
bool havePath(char *matrix,const char *str,int rows,int cols);
bool findPath(char *matrix,const char *str,int rows,int cols,int row,int col,bool *visted,int &stepLen);
void test1();
void test2();
void test3();
void test4();
int main(){
char matrix[] = "abtgcfcsjdeh";
const char *str = "bfce";
cout<<"径阵路径如下:"<<endl;
show(matrix,3,4);
cout<<endl;
bool haspath = havePath(matrix,str,3,4);
cout<<str<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
test1();
test2();
test3();//只有一行
test4();//空矩阵
return 0;
}
void test2(){
char matrix[] = "ABTGCFCSJDEH";
const char *str = "ABFB";
cout<<"径阵路径如下:"<<endl;
show(matrix,3,4);
cout<<endl;
bool haspath = havePath(matrix,str,3,4);
cout<<str<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
}
void test1(){
char matrix1[] = "ABCESFCSADEE";
const char *str1 = "SEE";
cout<<"径阵路径如下:"<<endl;
show(matrix1,3,4);
cout<<endl;
bool haspath = havePath(matrix1,str1,3,4);
cout<<str1<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
}
void test3(){
char matrix1[] = "ABCE";
const char *str1 = "SEE";
cout<<"径阵路径如下:"<<endl;
show(matrix1,1,4);
cout<<endl;
bool haspath = havePath(matrix1,str1,3,4);
cout<<str1<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
}
void test4(){
char *matrix1 = nullptr;
const char *str1 = "SEE";
cout<<"径阵路径如下:"<<endl;
show(matrix1,1,4);
cout<<endl;
bool haspath = havePath(matrix1,str1,3,4);
cout<<str1<<" ";
if(haspath)
cout<<"找到符号路线"<<endl<<endl;
else
cout<<"没找到符号路线"<<endl<<endl;
}
bool havePath(char *matrix,const char *str,int rows,int cols){
if(matrix == nullptr || rows < 0 || cols < 0)
return false;
//string.h 或 memory.h
bool *visted = new bool[rows * cols];
memset(visted,0,sizeof(visted));//全部置为0,即false
bool haspath = false;
int stepLen = 0;
//矩阵图中同一个字符可能有多次出现,所以要找不同的起点
for(int row=0;row<rows;row++){
for(int col=0;col<cols;col++){
haspath = findPath(matrix,str,rows,cols,row,col,visted,stepLen);
if(haspath == true)
return true;
}
}
delete []visted;
return false;
}
bool findPath(char *matrix,const char *str,int rows,int cols,int row,int col,bool *visted,int &stepLen){
if(matrix == nullptr || str == nullptr)
return false;
if(rows < 1 || cols < 1 || row < 0 || row >= rows || col < 0 || col >= cols)
return false;
if(str[stepLen] == '\0')//找到完整字符串,结束条件
return true;
bool isFind = false;
if( (str[stepLen] == matrix[row * cols + col]) && (visted[row * cols + col] == false) )
{
visted[row * cols + col] = true;
stepLen++;
isFind = findPath(matrix,str,rows,cols,row,col-1,visted,stepLen)//左
|| findPath(matrix,str,rows,cols,row,col+1,visted,stepLen)
|| findPath(matrix,str,rows,cols,row-1,col,visted,stepLen)
|| findPath(matrix,str,rows,cols,row+1,col,visted,stepLen);
//注意这个步数回朔只能放在if内,而不能放在上面的if外
//因为只有在这个if内stepLen才会++,所以这里才能回朔--
if(isFind == false){
stepLen--;
visted[row * cols + col] = false;
}
}
return isFind;
}
void show(char *matrix,int rows,int cols){
if(matrix == nullptr)
return;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
cout<<matrix[i*cols+j]<<" ";
}
cout<<endl;
}
}
运行结果如下: