请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
注意:
1.应该有一个布尔值矩阵来记录矩阵的哪些格子已经被使用过了
2.使用递归的方式求解。在使用递归的时候应该注意,在退出递归的时候需要根据需求对计数或者标志进行回退或者清除等操作。
class Solution {
public:
//回溯法进行矩阵中的路径判断
//输入:源数组 matrix, 行数 rows, 列数 cols,目标字符串 str
//输出:有目标路径 true, 无解 false
bool hasPath(const char* matrix, int rows, int cols,const char* str){
//1.检查输入变量的合法性
if(matrix == nullptr || rows <= 0 || cols <= 0 || str == nullptr)
return false;
//2.标记变量数组的声明与初始化
bool* visited = new bool[rows * cols]; //动态内存分配:new 类型名(初始化参数列表)
memset(visited,0,rows * cols); //初始化数组元素的值
//3.遍历所有可选项,从可选项中选出符合条件的位置,进行回溯
int pathlength = 0; //递归深度
for (int i = 0; i < rows; ++i){
for (int j = 0; j < cols; ++j){
if (hasPathCore(matrix, rows, cols, str, i, j, pathlength, visited)) //调用一个函数,这个函数从可选项中选出符合条件的位置,进行回溯,并会返回bool值
return true; //有目标路径返回true
}
}
//释放动态分配的内存空间
delete [] visited;
return false; //无目标路径返回false
}
//递归方法实现回溯
//输入:源数组 matrix, 行数 rows, 列数 cols,目标字符串 str,遍历深度 pathlength,标记数组 visited
//输出:有目标路径 true, 无解 false
bool hasPathCore(const char* matrix, int rows, int cols,const char* str, int i, int j, int pathlength, bool* visited){
//0.递归结束条件,找到目标路径,回溯结束
if(str[pathlength] == '\0') //字符串常量的本质是其首地址
return true;
bool haspath = false; //默认无目标路径
//1.递归判断条件,继续递归or返回结果。从可选项中选出符合条件(当前格子和路径字符串中下标为pathlength的字符一样时)的位置,进行回溯
if(i >= 0 && i < rows && j >= 0 && j < cols && matrix[i * cols + j] == str[pathlength] && !visited[i * cols + j]){
++pathlength;
visited[i * cols + j] = 1;
//2.递归公式,从可选项中找出符合条件的选项,进行下一次递归
haspath = hasPathCore(matrix, rows, cols,str,i - 1, j, pathlength, visited)
|| hasPathCore(matrix, rows, cols,str,i + 1, j, pathlength, visited)
|| hasPathCore(matrix, rows, cols,str,i, j - 1, pathlength, visited)
|| hasPathCore(matrix, rows, cols,str,i, j + 1, pathlength, visited);
//3.可选项中没有符合条件的结果,退回上一个步骤
if (!haspath){
--pathlength;
visited[i * cols + j] = 0;
}
}
return haspath;
}
};