问题描述:
input:一个矩阵matrix,总行数rows,总列数cols,一个字符串str
output:矩阵中是否存在满足字符串str的路径
判断矩阵中是否有满足字符串的路径,(1)路径可以从任意位置开始,(2)在矩阵的某一位置可以向上下左右四个方向走,(3)走过的位置不能重复走
解法:
回溯法简介:
适合由多个步骤组成的问题,每个步骤有多个选项,
流程:(1)在某一步骤中选择了其中一个选项时,就进入了下一步骤,然后又面临新的选项;
(2)如果下一步骤中尝试所有的选项都没有满足要求,就回到到上一步骤尝试其他选项;(回溯)
(3)就这样重复选择的过程直至到达最终的状态。
思想:
(1)在matrix中找到路径的入口(遍历matrix,找到matrix[row][col] == str[0])
(2)维护一个visited矩阵,用来记录对应矩阵位置是否已经走过
(3)首先判断当前的row,col是否溢出;再判断是否达到递归终止条件(字符串str已经匹配完成,达到末尾---到达最终状态)
(3)如果满足visited = 0 && 当前位置的值==str[str_i],开始递归,先将当前位置的visited[row][col] = 1,深度优先遍历,逐一递归进入当前位置的上下左右四个位置(四个选项),递归函数的参数路径长度str_i + 1
(4)如果上下左右四个选项都不满足条件,说明当前位置matrix[row][col]不能在路径中(上一步选项选错了),将visited[row][col]重新置为0,return false并回到上一步尝试其他选项。
own:
tips:
(1)由于传入的是matrix指针,所以不能用下标的形式访问矩阵元素,对于matrix[row][col]应该用matrix[row * cols + col]
(2)注意边界值,如:'A',1,1,'A'这种情况,要注意两个if语句的先后顺序,先进行递归终止条件的判断
class Solution {
public:
//如何初始化一个全0矩阵?
bool hasPath(char* matrix, int rows, int cols, char* str)
{
if(matrix == NULL || str == NULL || !rows || !cols)
return false;
//error: int *visited[rows][cols];
bool *visited = new bool[rows * cols];
memset(visited, 0, rows * cols);
for(int row = 0; row < rows; row++)
{
for(int col = 0; col < cols; col++)
{
if(matrix[row * cols + col] == str[0])
{
if(FindPath(matrix, rows, cols, str, row, col, 0, visited))
return true;
}
}
}
return false;
}
bool FindPath(char* matrix, int rows, int cols, char* str, int row, int col, int str_i, bool* visited)
{
if(str[str_i] == '\0')
return true;
//注意if的先后顺序,如果'\0'条件放在后面的话,当matrix中只有一个字符的时候传进来的参数不满足下面这个条件会return false,但是其实是是应该return true
//如:'A',1,1,'A'这种情况
//**以下两个if语句可以写成一个,即要满足行列在合法范围,没有访问过,元素值==str[str_i]的矩阵元素才会作为选项进入递归
if(row >= rows || col >= cols || row < 0 || col < 0)
{
return false;
}
if(visited[row * cols + col] == 0 && matrix[row * cols + col] == str[str_i])
{
visited[row * cols + col] = 1;
if(FindPath(matrix, rows, cols, str, row - 1, col, str_i + 1, visited) ||
FindPath(matrix, rows, cols, str, row + 1, col, str_i + 1, visited) ||
FindPath(matrix, rows, cols, str, row, col - 1, str_i + 1, visited) ||
FindPath(matrix, rows, cols, str, row, col + 1, str_i + 1, visited)
)
{
return true;
}
else
{
visited[row * cols + col] = 0;
}
}
return false;
}
};