判空
这样写也能过:
if(matrix==nullptr)return NULL;
但是不完善,因为这是牛客的测试用例没写完善,我们应该多加几个判空条件:
if (matrix == nullptr || rows < 0 || cols < 0 || str == NULL)return false;
0.
在 C++ 中,当你声明一个布尔类型的变量时(例如 bool flag),它被初始化为 false 是默认的行为。这是因为布尔类型变量只有两种状态:true 和 false,而 false 是默认状态。
bool flag=new bool[rows*cols];
1.
这段代码是使用回溯法在二维数组 matrix 中查找字符串 str。flag 是一个布尔数组,用于记录当前位置是否已经被访问过。judge 函数负责判断当前位置是否符合条件,如果符合条件,则返回 true。
代码的逻辑如下:
- 遍历二维数组的每一行和每一列,对于每个位置
(i, j),首先判断该位置是否已经被访问过(即flag[i*cols+j]为true)。 - 如果当前位置已经被访问过,则跳过该位置,继续遍历下一个位置。
- 如果当前位置未被访问过,则将当前位置标记为已访问(即
flag[i*cols+j] = true),并调用judge函数判断当前位置是否符合条件。 - 如果
judge函数返回true,则说明找到了字符串str的起始位置,返回true。 - 如果
judge函数返回false,则继续遍历下一个位置。 这种回溯法可以有效地查找字符串str在二维数组matrix中的起始位置。如果找到了起始位置,函数将返回true,否则返回false。
for (int j = 0; j < cols; j++) {
//循环遍历二维数组,找到起点等于str第一个元素的值,再递归判断四周是否有符合条件的----回溯法
if (judge(matrix, i, j, rows, cols, flag, str, 0)) {
return true;
}
}
}
3
bool judge(char[] matrix,int i,int j,int rows,int cols,boolean[] flag,char[] str,int k){
//先根据i和j计算匹配的第一个元素转为一维数组的位置
int index = i*cols+j;
//递归终止条件
if(i<0 || j<0 || i>=rows || j>=cols || matrix[index] != str[k] || flag[index] == true)
return false;
4.
//若k已经到达str末尾了,说明之前的都已经匹配成功了,直接返回true即可
if(k == str.length-1)return true
F[index] = true;
5.
例如i为1,j为4时:
代码:
```js
private boolean judge(char[] matrix,int i,int j,int rows,int cols,boolean[] flag,char[] str,int k)
{
}
if(judge(matrix,i-1,j,rows,cols,flag,str,k+1) ||
judge(matrix,i+1,j,rows,cols,flag,str,k+1) ||
judge(matrix,i,j-1,rows,cols,flag,str,k+1) ||
judge(matrix,i,j+1,rows,cols,flag,str,k+1) )
{
return true;
}
这段代码是一个递归函数 judge 的调用,它的作用是从矩阵的四个角落开始尝试搜索是否存在一条路径,满足从当前位置出发,按照给定的字符串 str 的顺序访问矩阵中的元素。
函数 judge 的参数如下:
matrix:一个二维数组,表示矩阵。i和j:表示当前遍历到的位置。rows和cols:分别表示矩阵的行数和列数。flag:一个布尔数组,用于记录当前位置是否已经被访问过。str:一个字符串,表示需要匹配的字符串。k:表示str的当前匹配位置。 这段代码的逻辑如下:
- 首先,判断当前位置 (i, j) 是否在矩阵的范围内,即
i >= 0和j >= 0且i < rows和j < cols。 - 如果当前位置的元素
matrix[i][j]等于str[k],那么尝试从当前位置继续匹配。 - 如果当前位置已经被访问过(即
flag[i*cols+j]为true),那么继续匹配。 - 如果
k已经到达字符串str的末尾,那么说明当前位置已经匹配成功,返回true。 - 如果当前位置的元素满足上述条件,那么递归地尝试从四个角落继续匹配:
judge(matrix, i-1, j, rows, cols, flag, str, k+1)、judge(matrix, i+1, j, rows, cols, flag, str, k+1)、judge(matrix, i, j-1, rows, cols, flag, str, k+1)和judge(matrix, i, j+1, rows, cols, flag, str, k+1)。 - 如果递归调用中的任何一条路径匹配成功,那么返回
true,否则继续搜索其他路径。 这段代码的主要目的是搜索矩阵中是否存在一条从起始位置到结束位置的路径,满足路径上的每个元素都按照给定的字符串str的顺序访问。
6.
//走到这,说明这一条路不通,还原,再试其他的路径
flag[index] = false;
return false;
但是会有报错:
显示F不是指针或者数组,不能访问下标:
但是实际上布尔值是可以访问下标的,但是需要变为指针,也就是bool*:
在此之前我们还要对F[index]所有元素进行初始化为false。
并且在使用memset初始化时需要注意,否则会报错:
全部代码:
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str) {
//判空
//if(matrix==nullptr)return NULL;
if (matrix == nullptr || rows < 0 || cols < 0 || str == NULL)return false;
//首先写一个表示是否走过的变量
bool* F = new bool[rows * cols];
memset(F,false,rows*cols);
//遍历
for (int i = 0; i < rows;i++) {
for (int j = 0; j < cols; j++) {
if (jude(matrix, i, j, rows, cols, F, str,0)) {
return true;
}
}
}
delete[ ] F;
return false;
}
//jude函数的实现
bool jude(char* matrix, int i, int j, int rows, int cols, bool* F, char str[],int k) {
//遍历每一位元素
int index = i * cols + j;
int length = strlen(str);
//递归结束条件
if (i < 0 || j < 0 || i >= rows || j >= cols || matrix[index] != str[k] ||F[index] == true) {
return false;
}
//k遍历到最后说明全部走完了,赋值为true
if(k==length-1) return true;
F[index] = true;
//递归
//向左向右向上向下递归,找到返回true,否则返回flase
if (
jude(matrix, i - 1, j, rows, cols, F, str, k+1) ||
jude(matrix, i + 1, j, rows, cols, F, str, k+1) ||
jude(matrix, i, j - 1, rows, cols, F, str, k+1) ||
jude(matrix, i, j + 1, rows, cols, F, str, k+1)
) {
return true;
}
//走到这一步就是没有找到,那就返回false
F[index] = false;
return false;
}
};