剑指Offer面试题12: 矩阵中的路径

80 篇文章 0 订阅
80 篇文章 13 订阅

题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 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;
	}
}

运行结果如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值