题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 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)
{
char HasGo[rows][cols];
if(str == NULL) return false;
if(*str == '\0') return true;
bool res = false;
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; i++)
HasGo[i][j] = '0';
}
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
while(!res)
{
if(matrix[i][j] == *str)
{
bool res = hasPathCore(matrix, rows, cols, i, j, str, HasGo);
}
}
if(res)
return true;
}
}
return false;
}
bool hasPathCore(char* matrix, int rows, int cols, int i, int j, char* str, char* HasGo)
{
if(matrix[i][j] != *str || HasGo[i][j] != '0')
return false;
HasGo[i][j] = '1';
if(*(++str) != '\0')
{
if(HasGo[i+1][j] == '0' && i+1 < rows && j < cols)
return hasPathCore(matrix, rows, cols, i+1, j, str, HasGo);
if(HasGo[i-1][j] == '0' && i-1 < rows && j < cols)
return hasPathCore(matrix, rows, cols, i-1, j, str, HasGo);
if(HasGo[i][j+1] == '0' && i < rows && j+1 < cols)
return hasPathCore(matrix, rows, cols, i, j+1, str, HasGo);
if(HasGo[i][j-1] == '0' && i < rows && j-1 < cols)
return hasPathCore(matrix, rows, cols, i, j-1, str, HasGo);
}
else
return true;
}
};
递归层次不清晰,一些变量的设置,变化也不正确:
(1)越界检查放在递归函数最前面,更简洁明了;
(2)不能++str,因为如果后面走不通,要验证的字符位置不能还原。下面用 k+1 表示要验证的位置;
(3)如果当前位置的上下左右都走不通,那么当前位置往下就走不通,更改标记!!返回false 。
别人的代码
用一个状态数组保存之前访问过的字符,然后再分别按上,下,左,右递归
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
int* flag = new int[rows*cols];
if(str == NULL) return false;
if(*str == '\0') return true;
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
if(hasPathCore(matrix, rows, cols, i, j, str, 0, flag))
return true;
}
}
return false;
}
bool hasPathCore(char* matrix, int rows, int cols, int i, int j, char* str, int k, int* flag)
{
int index = i * cols + j;
if(i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index] == 1)
return false;
if(str[k + 1] == '\0') // 该位置是最后一个有效字符
return true;
flag[index] = 1;
if(hasPathCore(matrix, rows, cols, i+1, j, str, k+1, flag)
|| hasPathCore(matrix, rows, cols, i-1, j, str, k+1, flag)
|| hasPathCore(matrix, rows, cols, i, j+1, str, k+1, flag)
|| hasPathCore(matrix, rows, cols, i, j-1, str, k+1, flag))
{
return true;
}
flag[index] = 0; // 从该位置往后上下左右都走不通,还原该位置标记
return false;
}
};