leetcode
leetcode 2851 ~ 2900
最小跳跃次数

最小跳跃次数

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 244 ms, 内存: 79.4 MB


/*
 * 思路:
 * 1. 通过使用队列来实现BFS来找到最小按动次数。
 * 2. 由于Java Stream不适合在此场景下实现BFS,因此保持逻辑不变。
 * 3. 仍然是计算向右和向左弹射的所有可能性。
 */

import java.util.stream.IntStream;
import java.util.LinkedList;
import java.util.Queue;

public class SpringGameStream {
    public int minJumps(int[] jump) {
        int n = jump.length;
        boolean[] visited = new boolean[n];
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0, 0});
        visited[0] = true;
        int maxReach = 0;

        while (!queue.isEmpty()) {
            int[] current = queue.poll();
            int index = current[0];
            int step = current[1];

            int nextIndex = index + jump[index];
            if (nextIndex >= n) {
                return step + 1;
            }
            if (!visited[nextIndex]) {
                visited[nextIndex] = true;
                queue.offer(new int[]{nextIndex, step + 1});
            }

            final int finalMaxReach = maxReach;
            IntStream.range(finalMaxReach, index).filter(i -> !visited[i]).forEach(i -> {
                visited[i] = true;
                queue.offer(new int[]{i, step + 1});
            });

            maxReach = Math.max(maxReach, index);
        }
        return -1;
    }
}

解释

方法:

The solution uses a breadth-first search (BFS) strategy, where each position on the springboard array 'jump' is treated as a node in a graph, and the possible jumps from each node define the edges. Starting from the first spring (index 0), the algorithm explores all possible jumps (both forward to 'i + jump[i]' and backward to any index less than 'i'). A queue is used to keep track of the next indices to visit. The 'visited_status' set ensures each index is only added once to the queue to prevent infinite loops. The BFS approach guarantees that the first time the algorithm reaches beyond the last index (N), the minimum number of moves has been found.

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在解决此问题时,为什么选择使用宽度优先搜索(BFS)而不是深度优先搜索(DFS)或其他方法?
在此问题中,使用宽度优先搜索(BFS)是因为我们需要找到从起点到终点的最短跳跃次数。BFS从起点开始,逐层探索所有可能的跳跃路径,确保一旦到达终点时,所用的跳跃次数是最少的。相比之下,深度优先搜索(DFS)可能会深入探索某一路径直到终点,但这不一定是最短跳跃路径。BFS通过逐层探索保证了一旦找到解决方案,那么它就是需要的最小跳跃次数。
🦆
代码中提到的`visited_status`集合是如何帮助防止无限循环的?具体是通过什么机制实现的?
`visited_status`集合存储了所有已经访问过的索引。在BFS过程中,每次访问一个新的索引前会检查该索引是否已在`visited_status`中。如果已存在,则不会再次将其加入待访问队列。这个机制有效防止了算法重复访问同一索引,避免了无限循环并减少了不必要的计算,保证了算法的效率和正确性。
🦆
为什么需要一个单独的变量`left_max_vis_idx`来跟踪访问过的最左边的索引?这与普通的BFS有什么不同?
变量`left_max_vis_idx`用于追踪在进行正向跳跃时,已经考虑过的最左边的索引位置。在BFS中,除了正向跳跃外,还需要考虑向所有未访问的更小索引的反向跳跃。`left_max_vis_idx`确保算法在向后遍历并将这些索引加入队列时不会重复访问已经处理过的索引。这种处理方式是对传统BFS的一个扩展,特别适用于跳跃问题,因为它需要同时处理向前和向后的跳跃条件,而且向后的跳跃需确保不遗漏任何可能的路径。

相关问题