题目:机器人的运动范围
答案:
参考链接:BFS+DFS
矩阵路径的求解方法可以归结为图或树的遍历/搜索方法,而图的通用搜索算法就是BFS(广度优先搜索)和DFS(优先搜索)。
1.深度优先算法
DFS遍历节点时,满足本题条件则计数符加1,并设置该节点标志为true,同时判断该节点的子节点是否也满足本题条件,进行递归操作。
class Solution {
public int movingCount(int m, int n, int k) {
boolean[][] isViewed = new boolean[m][n];
//计数符
int[] count = new int[1];
dfs(m, n, k, 0, 0, count, isViewed);
return count[0];
}
//深度优先搜索
private static void dfs(int m, int n, int k, int i, int j, int[] count, boolean[][] visit) {
//满足位数和小于k
if (sum(i) + sum(j) <= k) {
//满足条件的数量+1
count[0]++;
//该格子被访问过
visit[i][j] = true;
//判断向右+1:(i+1, j),在矩阵内,且未被访问过
if (i + 1 >= 0 && i + 1 < m && j >= 0 && j < n && !visit[i + 1][j]) {
dfs(m, n, k, i + 1, j, count, visit);
}
//判断向下+1:(i, j+1),在矩阵内,且未被访问过
if (i >= 0 && i < m && j + 1 >= 0 && j + 1 < n && !visit[i][j + 1]) {
dfs(m, n, k, i, j + 1, count, visit);
}
}
}
//计算整数位数和函数
private static int sum(int n) {
int s = 0;
while (n > 0) {
s += n % 10;
n /= 10;
}
return s;
}
}
2.广度优先算法
BFS算法使用队列实现,当队列不为空,即取出队列的队首节点,并计数符加1,同时判断该节点的子节点是否满足题目条件,如果满足则push到队列的队尾,循环继续。本题从(0,0)开始,所以只需考虑向右(x+1,y)和向下(x,y+1)。
class Solution {
public int movingCount(int m, int n, int k) {
boolean[][] isViewed = new boolean[m][n];
//计数符
int[] count = new int[1];
Queue<int[]> queue= new LinkedList<int[]>();
queue.add(new int[] {0, 0});
bfs(m, n, k, count, isViewed, queue);
return count[0];
}
//广度优先搜索
private static void bfs(int m, int n, int k, int[] count, boolean[][] visit, Queue<int[]> queue) {
while (!queue.isEmpty()) {
//取出队首节点
int[] p = queue.poll();
//将计数+1
count[0]++;
int i = p[0];
int j = p[1];
if (i + 1 >= 0 && i + 1 < m && j >= 0 && j < n &&
sum(i + 1) + sum(j) <= k && !visit[i + 1][j]) {
queue.add(new int[] {i+1, j});
visit[i + 1][j] = true;
}
if (i >= 0 && i < m && j + 1 >= 0 && j + 1 < n &&
sum(i) + sum(j + 1) <= k && !visit[i][j + 1]) {
queue.add(new int[] {i, j+1});
visit[i][j + 1] = true;
}
}
}
//计算整数位数和函数
private static int sum(int n) {
int s = 0;
while (n > 0) {
s += n % 10;
n /= 10;
}
return s;
}
}