题目
比如在以下的3*4的矩阵中包括一条字符串”bcced”的路径。
但矩阵中不包括字符串“abcb”的路径,因为字符串的第一个字符b占领了矩阵中的第一行第二格子之后,路径不能再次进入这个格子。
a b c e
s f c s
a d e e
解题思路
分析:回溯算法
这是一个可以用回朔法解决的典型题。首先,在矩阵中任选一个格子作为路径的起点。如果路径上的第i个字符不是ch,那么这个格子不可能处在路径上的
第i个位置。如果路径上的第i个字符正好是ch,那么往相邻的格子寻找路径上的第i+1个字符。除在矩阵边界上的格子之外,其他格子都有4个相邻的格子。
重复这个过程直到路径上的所有字符都在矩阵中找到相应的位置。
由于回朔法的递归特性,路径可以被开成一个栈。当在矩阵中定位了路径中前n个字符的位置之后,在与第n个字符对应的格子的周围都没有找到第n+1个
字符,这个时候只要在路径上回到第n-1个字符,重新定位第n个字符。
由于路径不能重复进入矩阵的格子,还需要定义和字符矩阵大小一样的布尔值矩阵,用来标识路径是否已经进入每个格子。 当矩阵中坐标为(row,col)的
格子和路径字符串中相应的字符一样时,从4个相邻的格子(row,col-1),(row-1,col),(row,col+1)以及(row+1,col)中去定位路径字符串中下一个字符
如果4个相邻的格子都没有匹配字符串中下一个的字符,表明当前路径字符串中字符在矩阵中的定位不正确,我们需要回到前一个,然后重新定位。
一直重复这个过程,直到路径字符串上所有字符都在矩阵中找到合适的位置
class Solution { public: bool hasPath(char* matrix, int rows, int cols, char* str) { if(!matrix||!str) return false; vector<vector<bool>> flag(rows,vector<bool>(cols,false)); int len=0; for(int i=0;i<rows;++i) { for(int j=0;j<cols;++j) if(hasPathCore(i,j,rows,cols,len,matrix,str,flag)) return true; } return false; } private: bool hasPathCore(int i,int j,int rows,int cols,int len,char *matrix,char *str,vector<vector<bool>> &flag) { if(str[len]=='') return true; bool hasPath=false; if(i>=0&&i<rows&&j>=0&&j<cols&&str[len]==matrix[i*cols+j]&&!flag[i][j]) { ++len; flag[i][j]=true; hasPath=hasPathCore(i+1,j,rows,cols,len,matrix,str,flag)|| hasPathCore(i-1,j,rows,cols,len,matrix,str,flag)|| hasPathCore(i,j+1,rows,cols,len,matrix,str,flag)|| hasPathCore(i,j-1,rows,cols,len,matrix,str,flag); if(!hasPath) { --len; flag[i][j]=false; } } return hasPath; } };