Sweaty Imposter

Jump Game II

MediumGreedyNeetCode 150MidOpen on LeetCodeUpdated

You're given an integer array nums and you start at index 0. nums[i] is your maximum jump length from index i, so from i you can land on any index from i + 1 to i + nums[i]. Return the minimum number of jumps needed to reach the last index. The input always allows reaching the last index, and if the array has only one element you're already there, so the answer is 0.

Examples

nums = [2,3,1,1,4] returns 2

Jump from index 0 to index 1, then 3 steps from index 1 to the last index (4). One jump isn't enough, because index 0 reaches at most index 2.

nums = [2,3,0,1,4] returns 2

Again go 0 -> 1 -> 4, since index 1 (value 3) reaches the end. Index 2 holds 0 and would be a dead end, but you never need to land there.

nums = [0] returns 0

With one element you start on the last index, so no jump is needed.

Constraints

  • 1 <= nums.length <= 10^4
  • 0 <= nums[i] <= 1000
  • It's guaranteed that you can reach nums[n - 1].

Hints

Hint 1

Group indices by how many jumps it takes to reach them. Which indices can you reach with 0 jumps, with 1 jump, with 2?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

The indices reachable in exactly k jumps form a contiguous range [left, right], like one level of a breadth-first search. Start with [0, 0]. Scan the range for the farthest index any position in it can reach; the next range is right + 1 through that farthest index, and it costs one more jump. Stop once the range covers the last index. Each index is scanned once.

Time

O(n)

Space

O(1)

Pitfall

Always taking the longest jump from where you stand fails: in [2,3,1,1,4] it goes 0 -> 2 -> 3 -> 4 for 3 jumps. What matters is the farthest reach across the whole current range, not the biggest single jump.

Solutions

class Solution {
    public int jump(int[] nums) {
        int jumps = 0;
        int left = 0, right = 0;
        while (right < nums.length - 1) {
            int farthest = 0;
            for (int i = left; i <= right; i++) {
                farthest = Math.max(farthest, i + nums[i]);
            }
            left = right + 1;
            right = farthest;
            jumps++;
        }
        return jumps;
    }
}
Drill This