BFS(广度优先搜索)
这是一个使用动态规划方法解决“按数组中的元素和行走”问题的代码。下面是逐行代码解析:
class Solution {:定义一个名为Solution的公共类。public int movingCount(int threshold, int rows, int cols) {:定义一个名为movingCount的公共方法,接收三个参数:阈值(表示数组中元素的和)、行数和列数。bool** isVisited = new bool*[rows];:创建一个二维布尔指针数组isVisited,用于记录是否已经走过。for (int i = 0; i < rows; i++) {:遍历行数组。isVisited[i] = new bool[cols];:为每一行分配一个布尔数组。for (int j = 0; j < cols; j++) {:遍历列数组。isVisited[i][j] = false;:初始化所有元素为未走过。}:结束列遍历。}:结束行遍历。int count = jude(threshold, rows, cols, 0, 0, isVisited);:调用jude方法,传入阈值、行数、列数、初始位置(0, 0)和isVisited数组,获取走过格子数。for (int i = 0; i < rows; i++) {:遍历行数组。delete[] isVisited[i];:释放每一行的内存。}:结束行遍历。delete[] isVisited;:释放二维指针数组。return count;:返回计算结果。
jude方法解析:
int jude(int threshold, int rows, int cols, int i, int j, bool** isVisited) {:定义一个名为jude的递归方法,接收五个参数:阈值、行数、列数、初始位置(i,j)和isVisited数组。if (i < 0 || j < 0 || i >= rows || j >= cols || isVisited[i][j] || nums(i) + nums(j) > threshold) {:判断当前位置是否合法,如果不合法则返回 0。isVisited[i][j] = true;:将当前位置标记为已走过。int count = jude(threshold, rows, cols, i - 1, j, isVisited) + jude(threshold, rows, cols, i + 1, j, isVisited) + jude(threshold, rows, cols, i, j - 1, isVisited) + jude(threshold, rows, cols, i, j + 1, isVisited) + 1;:递归调用jude方法,计算从当前位置向左、向右、向上和向下走的结果,并返回累加和。return count;:返回计算结果。nums方法解析:int nums(int n) {:定义一个名为nums的公共方法,接收一个整数参数n。int sum = 0;:初始化求和变量sum为 0。while (n > 0) {:使用do-while循环,当n不为 0 时执行以下操作。sum += n % 10;:将n的个位数加到sum中。}:结束循环。return sum;:返回计算结果。
注意点:
class Solution {
public:
int movingCount(int threshold, int rows, int cols) {
//首先判空
if (rows < 0 || cols < 0 || threshold < 0) return 0;
//写一个布尔型的变量表示是否走过
bool** isVisited = new bool*[rows];
for (int i = 0; i < rows; i++) {
isVisited[i] = new bool[cols];
for (int j = 0; j < cols; j++) {
isVisited[i][j] = false;
}
}
//是否走过交给 jude 函数进行判断
//每次递归的返回值给 count,count 记录走了多少个格子
int count = jude(threshold, rows, cols, 0, 0, isVisited);
//销毁
for (int i = 0; i < rows; i++) {
delete[] isVisited[i];
}
delete[] isVisited;
return count;
}
int jude(int threshold, int rows, int cols, int i, int j, bool** isVisited) {
//通过递归进行判断
//如果上下左右都走过,返回 true,否则返回 false
//递归结束条件:越界,全部走完了,还有坐标路径和大于阈值
if (i < 0 || j < 0 || i >= rows || j >= cols || isVisited[i][j]==true ||
nums(i) + nums(j) > threshold) {
return 0;
}
//将当前位置标记为已经走过了,再递归调用走另一个方向。
isVisited[i][j] = true;
//递归调用走上下左右,把上下左右的看路径相加,再加上1(当前位置)
int count = jude(threshold, rows, cols, i - 1, j, isVisited) +
jude(threshold, rows, cols, i + 1, j, isVisited) +
jude(threshold, rows, cols, i, j - 1, isVisited) +
jude(threshold, rows, cols, i, j + 1, isVisited) +
1;
return count;
}
//判断是否能进入方格
int nums(int n) {
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return sum;
}
};
DFS(深度优先搜索)
class Solution {
public:
int movingCount(int threshold, int rows, int cols) {
//首先判空
if (rows < 0 || cols < 0 || threshold < 0) return 0;
//写一个布尔型的变量表示是否走过
bool** isVisited = new bool*[rows];
for (int i = 0; i < rows; i++) {
isVisited[i] = new bool[cols];
for (int j = 0; j < cols; j++) {
isVisited[i][j] = false;
}
}
//是否走过交给 jude 函数进行判断
//每次递归的返回值给 count,count 记录走了多少个格子
int count = jude(threshold, rows, cols, 0, 0, isVisited);
//销毁
for (int i = 0; i < rows; i++) {
delete[] isVisited[i];
}
delete[] isVisited;
return count;
}
int jude(int threshold, int rows, int cols, int i, int j, bool** isVisited) {
//通过递归进行判断
//如果上下左右都走过,返回 true,否则返回 false
//递归结束条件:越界,下标值 false[i][j] 与不相同,全部走完了
if (i < 0 || j < 0 || i >= rows || j >= cols || isVisited[i][j]==true ||
nums(i) + nums(j) > threshold) {
return 0;
}
//将当前位置标记为已经走过了,再递归调用走另一个方向。
isVisited[i][j] = true;
//递归调用走上下左右,把上下左右的看路径相加,再加上本身这个 1
int count = //jude(threshold, rows, cols, i - 1, j, isVisited) +
jude(threshold, rows, cols, i + 1, j, isVisited) +
// jude(threshold, rows, cols, i, j - 1, isVisited) +
jude(threshold, rows, cols, i, j + 1, isVisited) +
1;
return count;
}
//判断是否能进入方格
int nums(int n) {
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return sum;
}
};
画图解析:
假如从A点开始访问,DFS就是沿着一条道走下去,然后再走其他的道……。BFS就是图中先访问圈内的部分,然后再把圈放大继续访问……。