获取食物的最短路径
难度:
标签:
题目描述
代码结果
运行时间: 80 ms, 内存: 22.4 MB
/*
* 思路:
* 1. 找到起点位置,并初始化一个队列用于BFS。
* 2. 使用一个方向数组遍历当前节点的四个邻居(上下左右)。
* 3. 如果邻居是空地或食物,且未被访问过,则将其加入队列并记录路径长度。
* 4. 遇到食物时,返回当前路径长度。
*/
import java.util.*;
import java.util.stream.*;
class Solution {
private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public int getFood(char[][] grid) {
int m = grid.length, n = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
boolean[][] visited = new boolean[m][n];
// Find the starting point using streams
IntStream.range(0, m).forEach(i ->
IntStream.range(0, n).filter(j -> grid[i][j] == 'S').forEach(j -> {
queue.offer(new int[]{i, j});
visited[i][j] = true;
})
);
int steps = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] current = queue.poll();
int x = current[0], y = current[1];
if (grid[x][y] == 'F') {
return steps;
}
Arrays.stream(DIRECTIONS).forEach(direction -> {
int nx = x + direction[0], ny = y + direction[1];
if (nx >= 0 && ny >= 0 && nx < m && ny < n && !visited[nx][ny] && grid[nx][ny] != '#') {
queue.offer(new int[]{nx, ny});
visited[nx][ny] = true;
}
});
}
steps++;
}
return -1; // If no path to food
}
}
解释
方法:
这个题解使用广度优先搜索(BFS)算法来解决问题。首先遍历网格,找到起始位置'*'的坐标。然后使用队列进行BFS,每次从队列中取出一个节点,探索其四个方向的相邻节点。如果找到食物'#',则返回当前的步数;如果未找到食物,则将未访问过且不是障碍物'X'的相邻节点加入队列,并标记为已访问。当队列为空时,表示无法到达食物,返回-1。
时间复杂度:
O(mn)
空间复杂度:
O(mn)
代码细节讲解
🦆
在BFS算法中,为什么要使用队列而不是其他数据结构如栈或优先队列?
▷🦆
如果起始位置 '*' 不存在于网格中,这段代码是否会正确处理这种情况?如果不会,应该如何修改代码以处理这种特殊情况?
▷🦆
在BFS中,每次从队列中取出一个节点时,你是如何保证不会重复访问同一个节点?具体是通过哪些操作实现的?
▷🦆
代码中提到的四个方向探索,是否考虑过使用其他探索路径优化策略,比如优先探索可能更接近目标的方向?这会对算法的效率有何影响?
▷