分析
这题是一道非常经典可以使用BFS也可以DFS的搜索题,题干有四连通。
①先做好一些初始工作:初始化队列、初始化记录状态的数组、初始化四连通数组
②接着就让队列一直循环
2.1 先从队列取值,再去掉队头
2.2 判断是否满足条件,若不满足就下一次循环
2.3 满足条件了,那就做题目中要求做的事。这题是要找能到达点有多少, 然后还要刷新状态
2.4 从中心点向四周扩散(四连通、八连通)
代码
bfs
class Solution {
public:
int q[3000][2];
int check(int a, int b) {
int s = 0;
while (a) {
s += a % 10;
a /= 10;
}
while (b) {
s += b % 10;
b /= 10;
}
return s;
}
int movingCount(int k, int rows, int cols)
{
//行数和列数都有可能为0
if (!rows | !cols)
return 0;
//st数组用于判断每个位置是否被遍历过
bool st[rows][cols];
memset(st, 0, sizeof st);
int hh = 0, tt = -1, ans = 0;
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
//将初始状态入队
q[++tt][0] = 0, q[tt][1] = 0;
while (hh <= tt) {
int a = q[hh][0], b = q[hh++][1];//取出队头元素
//每取出一个元素,都需要判断是否被遍历过,或者行坐标和列坐标的数位之和是否大于 k
if (st[a][b] || check(a, b) > k) continue;
//如果当前坐标没有被遍历过且行坐标和列坐标的数位之和小于等于k,则这个坐标是可以进入的
ans++;
st[a][b] = 1;
//向四连通方向遍历
for (int i = 0; i < 4; i++) {
int x = a + dx[i], y = b + dy[i];
if (x >= 0 && x < rows && y >= 0 && y < cols) {
q[++tt][0] = x, q[tt][1] = y;
}
}
}
return ans;
}
};
dfs
class Solution {
public:
//st数组用于判断每个位置是否被遍历过
bool st[51][51];
//偏移量数组
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
int ans;
int check(int a, int b) {
int s = 0;
while (a) {
s += a % 10;
a /= 10;
}
while (b) {
s += b % 10;
b /= 10;
}
return s;
}
void dfs(int a, int b, int k, int rows, int cols) {
//每遍历一个元素,都需要判断是否被遍历过,或者行坐标和列坐标的数位之和是否大于 k
if (st[a][b] || check(a, b) > k) return;
//如果当前坐标没有被遍历过且行坐标和列坐标的数位之和小于等于k,则这个坐标是可以进入的
ans++;
st[a][b] = 1;
//向四连通方向遍历
for (int i = 0; i < 4; i++) {
int x = a + dx[i], y = b + dy[i];
if (x >= 0 && x < rows && y >= 0 && y < cols) {
dfs(x, y, k, rows, cols);
}
}
}
int movingCount(int k, int rows, int cols)
{
//行数和列数都有可能为0
if (!rows | !cols)
return 0;
dfs(0, 0, k, rows, cols);
return ans;
}
};