跳跃游戏 III
难度:
标签:
题目描述
代码结果
运行时间: 29 ms, 内存: 34.7 MB
/*
题目思路:
1. 使用广度优先搜索(BFS)从起始位置开始遍历数组。
2. 使用队列来记录当前的跳跃位置。
3. 如果当前位置的值为0,返回true。
4. 否则,将当前位置跳跃的两个新位置加入队列。
5. 避免重复访问,通过一个布尔数组来标记访问过的位置。
6. 使用Java Stream来简化遍历的实现。
*/
import java.util.LinkedList;
import java.util.Queue;
import java.util.stream.IntStream;
public class SolutionStream {
public boolean canReach(int[] arr, int start) {
if (arr[start] == 0) return true;
int n = arr.length;
boolean[] visited = new boolean[n];
Queue<Integer> queue = new LinkedList<>();
queue.offer(start);
visited[start] = true;
while (!queue.isEmpty()) {
int current = queue.poll();
int forward = current + arr[current];
int backward = current - arr[current];
IntStream.of(forward, backward)
.filter(pos -> pos >= 0 && pos < n && !visited[pos])
.forEach(pos -> {
if (arr[pos] == 0) {
queue.clear();
queue.offer(-1); // to break the outer loop
} else {
queue.offer(pos);
visited[pos] = true;
}
});
if (!queue.isEmpty() && queue.peek() == -1) return true;
}
return false;
}
}
解释
方法:
本题采用深度优先搜索(DFS)的方法来解决。从起始索引 start 开始,尝试向数组的两个方向跳跃,即向右跳到 i + arr[i] 和向左跳到 i - arr[i],并递归地进行这一过程。为了避免重复访问相同的索引,使用一个集合 visited 记录已经访问过的索引。如果达到的位置的值为0,则成功找到一条路径,返回 true。如果尝试所有可能的跳跃后都未能找到值为0的位置,返回 false。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么选择深度优先搜索(DFS)而不是广度优先搜索(BFS)来解决这个问题?
▷🦆
在DFS实现中,如果数组中的数字非常大,是否会影响算法的性能?例如,如果 arr[i] 非常大,导致跳跃步长超过数组长度,这种情况如何处理?
▷🦆
递归实现中的栈溢出风险如何评估,尤其是在处理大数组时?
▷🦆
示例中的DFS逻辑是否考虑了所有可能的跳跃路径,还是只关注了首个找到的路径?
▷