Jump Game II: From Reachability to Minimum Jumps
Jump Game II (#45) is one of those LeetCode problems that looks intimidating at first glance but becomes elegant once you see the pattern. If you have already solved Jump Game (#55), you know how to check whether you can reach the last index. Jump Game II takes that a step further — it asks you to find the minimum number of jumps to get there.
This shift from "can you?" to "what is the fewest?" transforms the problem from a simple greedy check into an optimization challenge. The good news is that the same greedy intuition applies, but you need to think about it in terms of levels — like BFS without the queue.
In this walkthrough, we will break down the jump game ii leetcode problem, build the greedy BFS approach step by step, and walk through a visual example so the pattern sticks.
Understanding the Jump Game II Problem
You are given a zero-indexed array nums where each element nums[i] represents the maximum jump length from position i. Your goal is to reach the last index in the minimum number of jumps. The problem guarantees that you can always reach the last index — you do not need to worry about unreachable cases.
For example, given nums = [2,3,1,1,4], the answer is 2. You jump from index 0 to index 1 (jump length 1), then from index 1 to index 4 (jump length 3). That is two jumps to reach the end.
The brute-force approach would try every possible sequence of jumps using recursion or BFS with a queue, but that leads to O(n^2) or worse time complexity. The key insight of the leetcode 45 solution is that you do not need a queue at all — you can simulate BFS levels with just two variables.
The Greedy BFS Approach for Jump Game II
The core idea is to treat the problem like a BFS traversal where each "level" represents all the indices you can reach in one additional jump. You maintain two pointers: currentEnd marks the boundary of the current level, and farthest tracks the maximum index reachable from any position in this level.
As you iterate through the array, for each index i you update farthest to be the maximum of farthest and i + nums[i]. When i reaches currentEnd, you have exhausted the current level — you increment the jump counter and advance currentEnd to farthest. This is the moment you "take" a jump.
This approach works because you are always making the optimal choice: by scanning every position in the current level before jumping, you guarantee that the next level starts at the farthest possible reach. No backtracking, no queue, no extra space.
- currentEnd — the last index reachable with the current number of jumps (end of the current BFS level)
- farthest — the farthest index reachable from any position in the current level
- jumps — the counter that increments each time you finish a level
Key Insight
Think of it as BFS without a queue: currentEnd marks the end of the current 'level', farthest tracks the farthest reachable. When you hit currentEnd, you've exhausted this level — increment jumps.
Jump Game II Greedy Implementation
The implementation is remarkably concise. You initialize three variables: jumps = 0, currentEnd = 0, and farthest = 0. Then loop from index 0 to n - 2 (not n - 1 — more on that later). At each index, update farthest. When i equals currentEnd, increment jumps and set currentEnd to farthest.
Here is the logic in pseudocode: for each index i from 0 to n-2, set farthest = max(farthest, i + nums[i]). If i equals currentEnd, then jumps++ and currentEnd = farthest. After the loop, return jumps.
The time complexity is O(n) because you visit each index exactly once. The space complexity is O(1) since you only use three integer variables. This makes the jump game ii greedy solution optimal in both dimensions.
- 1Initialize jumps = 0, currentEnd = 0, farthest = 0
- 2Loop i from 0 to nums.length - 2
- 3At each i, update farthest = max(farthest, i + nums[i])
- 4If i == currentEnd, increment jumps and set currentEnd = farthest
- 5Return jumps after the loop completes
Visual Walkthrough: Minimum Jumps in Action
Let us trace through nums = [2,3,1,1,4] step by step. We start with jumps = 0, currentEnd = 0, and farthest = 0.
At index 0: nums[0] = 2, so farthest = max(0, 0+2) = 2. Since i == currentEnd (both 0), we increment jumps to 1 and set currentEnd = 2. This means level 1 covers indices 1 and 2.
At index 1: nums[1] = 3, so farthest = max(2, 1+3) = 4. Since i != currentEnd, we continue. At index 2: nums[2] = 1, so farthest = max(4, 2+1) = 4. Now i == currentEnd (both 2), so we increment jumps to 2 and set currentEnd = 4.
We are done iterating (we only go to n-2 = 3, but currentEnd is already 4 which is the last index). The answer is 2 jumps. Level 0 was index 0, level 1 was indices 1-2, and from level 1 we can reach the end.
- Level 0 (start): index 0 — can reach up to index 2
- Level 1 (1 jump): indices 1-2 — can reach up to index 4 (the end)
- Result: 2 jumps to reach the last index
Common Mistake
Don't iterate to the last index — iterate to n-2. If currentEnd is already at or past the last index, you don't need another jump. Iterating to n-1 can add an unnecessary extra jump.
Edge Cases for Jump Game II
There are a few edge cases worth considering for the minimum number of jumps problem. If the array has only one element, you are already at the last index, so the answer is 0 jumps. The loop from 0 to n-2 naturally handles this because when n=1, the loop body never executes.
If the first element is large enough to reach the end directly (e.g., nums = [5,1,1,1,1]), the answer is 1. At index 0, farthest becomes 5, i == currentEnd triggers, jumps becomes 1, and the loop ends.
Another scenario is when every element is 1 (e.g., [1,1,1,1]). You need exactly n-1 jumps. Each level covers just one more index, so the greedy approach counts one jump per index — straightforward but worth verifying your solution handles it correctly.
- Single element array — 0 jumps (already at end)
- First element reaches end — 1 jump
- All ones — n-1 jumps (each jump advances by 1)
- Large first element — still 1 jump if it covers the array
What Jump Game II Teaches You
Jump Game II is a textbook example of greedy BFS without a queue. The pattern of tracking currentEnd and farthest to simulate BFS levels appears in several other problems, including Jump Game III and some interval-based challenges. Once you internalize this level-based thinking, a whole class of optimization problems becomes approachable.
The problem also reinforces why greedy works when a problem has optimal substructure — at each level, the farthest you can reach is always the best choice, and you never need to reconsider. This is the same principle behind many greedy algorithm patterns on LeetCode.
If you have solved Jump Game (#55), solving Jump Game II is a natural next step. Practice recognizing when a problem shifts from feasibility to optimization — the greedy structure often stays the same, you just need to count steps. Review this pattern with YeetCode flashcards to lock it in before your next interview.
Follow-Up Problem
Jump Game II (#45) is the optimization follow-up to Jump Game (#55) — instead of 'can you reach the end?', it asks 'what's the minimum jumps?' Same greedy idea, slightly harder.