LeetCode #45 — Medium

Jump Game II

A complete visual walkthrough of the greedy BFS approach — from intuition to a clean O(n) solution.

Patterns Used

Roadmap

  1. The Brute Force — BFS / DP
  2. The Core Insight — Greedy Implicit BFS
  3. Walkthrough — Jump Levels for [2,3,1,1,4]
  4. Edge Cases
  5. Full Annotated Code
  6. Interactive Demo
  7. Complexity Analysis
Step 01

The Brute Force — BFS / DP

The straightforward approach treats this as a shortest path problem. From each index, you can jump to indices [i+1, i+nums[i]]. Use BFS to find the minimum jumps to reach the end.

BFS Approach

For [2, 3, 1, 1, 4], the BFS explores level by level:

Level 0: index 0 (value=2)
Level 1: indices 1, 2 (reachable in 1 jump)
Level 2: indices 3, 4 (reachable in 2 jumps) — index 4 is the end!

This works but BFS with a queue uses O(n) space and has overhead from queue operations.

💡

The BFS levels are contiguous ranges! Because we can jump to any index from i+1 to i+nums[i], each BFS level is a contiguous subarray. We don't need a queue at all — just track the range boundaries.

Step 02

The Core Insight — Greedy Implicit BFS

Instead of maintaining a queue, we track two boundaries: curEnd (the farthest index reachable in the current number of jumps) and farthest (the farthest index reachable from any position in the current level).

Three Variables, One Pass

jumps
Number of jumps taken so far
curEnd
End of current BFS level
farthest
Max reachable from this level

As we scan left to right, we update farthest = max(farthest, i + nums[i]). When i reaches curEnd, we've exhausted the current level — increment jumps and set curEnd = farthest.

Why greedy works here: At each BFS level, we want to reach as far as possible. Among all positions reachable in k jumps, the best next jump is the one that maximizes the new farthest point. Since we scan all positions in the level, we naturally find this maximum.

Step 03

Walkthrough — Jump Levels

Let's trace through [2, 3, 1, 1, 4] showing how the three variables evolve.

Array with Jump Ranges

2
i=0
3
i=1
1
i=2
1
i=3
4
i=4
lvl 0
lvl 1
lvl 2

Step-by-Step Trace

i=0: nums[0]=2
farthest = max(0, 0+2) = 2. i == curEnd(0), so jumps=1, curEnd=2.
i=1: nums[1]=3
farthest = max(2, 1+3) = 4. i != curEnd, continue.
i=2: nums[2]=1
farthest = max(4, 2+1) = 4. i == curEnd(2), so jumps=2, curEnd=4.
i=3: nums[3]=1
farthest = max(4, 3+1) = 4. i != curEnd, continue. Loop ends (i < n-1).
Answer: 2 jumps (0 → 1 → 4)
Step 04

Edge Cases

Single element
[0] → 0 jumps — already at the end. The loop condition i < nums.length - 1 ensures we don't process it.
Direct jump to end
[5,1,1,1,1] → 1 jump — from index 0 you can reach the end directly. The first level boundary at i=0 sets curEnd=4, and the loop ends.
All ones
[1,1,1,1] → 3 jumps — each BFS level contains exactly one index, so we need n-1 jumps. Worst case for this algorithm.
Step 05

Full Annotated Code

class Solution {
    public int jump(int[] nums) {

        int jumps = 0;        // number of jumps taken
        int curEnd = 0;      // end boundary of current BFS level
        int farthest = 0;    // farthest reachable from current level

        // Don't process the last index — we just need to reach it
        for (int i = 0; i < nums.length - 1; i++) {

            // Update the farthest we can reach
            farthest = Math.max(farthest, i + nums[i]);

            // Reached the end of current level?
            if (i == curEnd) {
                jumps++;               // take a jump
                curEnd = farthest;     // expand to next level
            }
        }

        return jumps;
    }
}
Step 06

Interactive Demo

Enter an array and watch the greedy BFS scan through, tracking jump levels and boundaries.

Jump Level Visualizer


Step 07

Complexity Analysis

Time
O(n)
Space
O(1)

We scan the array exactly once, doing O(1) work per index. No extra data structures — just three integer variables. This is optimal since we must read each element at least once.

📝

From O(n^2) BFS/DP to O(n) greedy. The key insight is that BFS levels form contiguous ranges, letting us replace the queue with two pointers. This pattern appears in many "minimum steps" problems — whenever levels are contiguous, greedy beats BFS.