Back to Arrays
Q47Question 47 of 109

Minimum Jumps to Reach the End (Fewest Jumps Across an Array)

Key Concepts
  • Each position stores the maximum jump length, and the goal is to reach the last index in the fewest jumps.
  • The DP recurrence is jumps[i] = min(jumps[j] + 1) for all j where j + arr[j] >= i.
  • The straightforward DP solution runs in O(N^2) time, acceptable for interview-sized inputs.
  • A greedy window optimization tracks the farthest reachable index and reduces time to O(N).
  • A sentinel value marks unreachable positions in the DP array.
  • If the first element is zero, the end is unreachable because you cannot move from the start.

Definition

The fewest jumps to reach a position is one plus the fewest jumps to the best reachable predecessor.
  • Minimum Jumps to Reach the End is a Fibonacci-family DP where each state depends on earlier states.
  • We fill a jumps[] array left to right, where jumps[i] is the fewest jumps to reach index i.
  • The recurrence is jumps[i] = min(jumps[j] + 1) for all j < i where j + arr[j] >= i.
  • Base case: jumps[0] = 0 because the start requires zero jumps.
  • A sentinel (e.g., Integer.MAX_VALUE) marks unreachable positions.
  • The straightforward DP is O(N^2); a greedy window refinement reaches O(N).

At the National Bank of India, the settlement pipeline has several processing stages. Each stage can skip ahead by up to a certain number of stages based on its clearance level. The operations team wants the fewest hops from the first stage to the last to estimate the fastest possible completion time. Minimum Jumps computes that fewest-hop count.

Understanding the Concepts

What is the Minimum Jumps problem?

Given an array of non-negative integers where each element represents the maximum number of positions you can jump forward from that index, find the minimum number of jumps needed to reach the last index from the first index. If the last index is unreachable, return -1.

For example, given [2, 3, 1, 1, 4], the minimum jumps are 2: jump from index 0 to index 1 (jump length 1), then from index 1 to index 4 (jump length 3).

How does the DP recurrence work?

We keep an array jumps[i] representing the fewest jumps to reach index i. We initialize all entries to a sentinel (Integer.MAX_VALUE) meaning unreachable, except jumps[0] = 0.

For each position i from 1 to n-1, we look at every earlier position j from 0 to i-1. If j + arr[j] >= i (meaning position j can reach position i) and jumps[j] is not the sentinel, then jumps[i] = Math.min(jumps[i], jumps[j] + 1).

JAVA
package com.bank.service;

public class MinJumpsService {

    /**
     * Finds minimum jumps to reach the last stage in the settlement pipeline.
     * O(N^2) DP approach.
     */
    public static int minJumpsDP(int[] stages) {
        int n = stages.length;
        if (n <= 1) return 0;

        int[] jumps = new int[n];
        java.util.Arrays.fill(jumps, Integer.MAX_VALUE);
        jumps[0] = 0;

        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (jumps[j] != Integer.MAX_VALUE && j + stages[j] >= i) {
                    jumps[i] = Math.min(jumps[i], jumps[j] + 1);
                }
            }
        }
        return jumps[n - 1] == Integer.MAX_VALUE ? -1 : jumps[n - 1];
    }

    public static void main(String[] args) {
        int[] pipeline = {2, 3, 1, 1, 4};
        System.out.println("Minimum hops: " + minJumpsDP(pipeline));
    }
}
TEXT
Minimum hops: 2

How does the greedy O(N) optimization work?

The greedy approach tracks three variables: the current number of jumps, the farthest index reachable within the current jump, and the farthest index reachable overall. We increment the jump count only when we must step beyond the current jump's window.

JAVA
package com.bank.service;

public class MinJumpsGreedyService {

    /**
     * Greedy O(N) approach for minimum jumps.
     * Used by the National Bank of India to find the fastest
     * pipeline path through settlement stages.
     */
    public static int minJumps(int[] stages) {
        int n = stages.length;
        if (n <= 1) return 0;
        if (stages[0] == 0) return -1; // Cannot move from start

        int jumps = 1;           // First jump from index 0
        int currentEnd = stages[0]; // Farthest reachable in current jump
        int farthest = stages[0];   // Farthest reachable overall

        for (int i = 1; i < n; i++) {
            if (i > farthest) return -1; // Unreachable
            if (i > currentEnd) {
                jumps++;
                currentEnd = farthest;
            }
            farthest = Math.max(farthest, i + stages[i]);
        }
        return jumps;
    }

    public static void main(String[] args) {
        int[] pipeline = {2, 3, 1, 1, 4};
        System.out.println("Minimum hops (greedy): " + minJumps(pipeline));

        int[] unreachable = {1, 0, 0, 0};
        System.out.println("Unreachable case: " + minJumps(unreachable));
    }
}
TEXT
Minimum hops (greedy): 2
Unreachable case: -1

How is the DP different from the greedy approach?

| Aspect | DP Approach | Greedy Approach |
|---|---|---|
| Time complexity | O(N^2) | O(N) |
| Space complexity | O(N) for jumps array | O(1) extra space |
| Can recover path? | Yes, with parent tracking | Not directly |
| Ease of reasoning | Straightforward recurrence | Requires invariant argument |
| Interview context | Good starting point | Expected optimization |

The DP is the correct starting point in an interview to show understanding of the recurrence. The greedy optimization is the follow-up that demonstrates deeper insight.

What are the edge cases?

Several edge cases require careful handling.

  • Single element: already at the end, answer is 0.
  • First element is zero: cannot move from the start, answer is -1.
  • Zero in the middle: may create an unreachable gap if no earlier position can jump past it.
  • All ones: requires exactly n-1 jumps.
  • First element covers the whole array: answer is 1.
JAVA
package com.bank.core;

public class MinJumpsEdgeCases {
    public static void main(String[] args) {
        System.out.println(minJumps(new int[]{5}));           // 0
        System.out.println(minJumps(new int[]{0, 1, 2}));     // -1
        System.out.println(minJumps(new int[]{1, 1, 1, 1}));  // 3
        System.out.println(minJumps(new int[]{10, 1, 1, 1})); // 1
    }

    static int minJumps(int[] arr) {
        int n = arr.length;
        if (n <= 1) return 0;
        if (arr[0] == 0) return -1;
        int jumps = 1, curEnd = arr[0], farthest = arr[0];
        for (int i = 1; i < n; i++) {
            if (i > farthest) return -1;
            if (i > curEnd) { jumps++; curEnd = farthest; }
            farthest = Math.max(farthest, i + arr[i]);
        }
        return jumps;
    }
}
TEXT
0
-1
3
1

What is the time and space complexity?

The DP approach runs in O(N^2) time because for each position we scan all predecessors. Space is O(N) for the jumps array. The greedy approach runs in O(N) time with O(1) extra space, making it optimal for large inputs.

How do you recover the actual jump path?

To recover which positions were jumped through, maintain a parent array alongside the jumps array in the DP version. Set parent[i] = j whenever jumps[i] is updated from position j, then backtrack from the last index through parents.

JAVA
package com.bank.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MinJumpsPathService {

    public static List<Integer> findPath(int[] stages) {
        int n = stages.length;
        int[] jumps = new int[n];
        int[] parent = new int[n];
        java.util.Arrays.fill(jumps, Integer.MAX_VALUE);
        jumps[0] = 0;
        parent[0] = -1;

        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (jumps[j] != Integer.MAX_VALUE
                        && j + stages[j] >= i
                        && jumps[j] + 1 < jumps[i]) {
                    jumps[i] = jumps[j] + 1;
                    parent[i] = j;
                }
            }
        }

        List<Integer> path = new ArrayList<>();
        for (int idx = n - 1; idx != -1; idx = parent[idx]) {
            path.add(idx);
        }
        Collections.reverse(path);
        return path;
    }

    public static void main(String[] args) {
        int[] pipeline = {2, 3, 1, 1, 4};
        System.out.println("Jump path: " + findPath(pipeline));
    }
}
TEXT
Jump path: [0, 1, 4]

What should a senior engineer know?

A senior engineer should understand these deeper aspects.

  • BFS interpretation: minimum jumps is equivalent to BFS on a graph where each index connects to all indices within its jump range. The greedy approach implicitly performs this BFS level by level.
  • Unreachable detection: the greedy approach detects unreachability when the current index exceeds the farthest reachable index, which is cleaner than checking a sentinel.
  • Relationship to Jump Game I: Jump Game I asks only whether the end is reachable (feasibility), while this problem asks for the minimum number of jumps (optimization). Both use the same farthest-reachable tracking.

What are common interview follow-up questions?

Interviewers often extend this problem.

  • Jump Game I: can you reach the end at all?
  • Jump Game with cost: each jump has a cost, minimize total cost.
  • Minimum jumps with backward jumps allowed: requires BFS on a graph.

Visual Overview

DIAGRAM
  Array:  [2, 3, 1, 1, 4]
  Index:   0  1  2  3  4

  ┌─────────────────────────────────────┐
  │  Greedy Window Tracking              │
  ├─────────────────────────────────────┤
  │  Start: jumps=1, curEnd=2, far=2    │
  │                                      │
  │  i=1: far = max(2, 1+3) = 4         │
  │  i=2: i > curEnd? No                 │
  │        far = max(4, 2+1) = 4         │
  │  i=3: i > curEnd(2)? Yes!            │
  │        jumps=2, curEnd=4             │
  │  i=4: reached end                    │
  │                                      │
  │  Result: 2 jumps                     │
  └─────────────────────────────────────┘
DIAGRAM
  Jump Reach Visualization:

  Index:  0     1     2     3     4
          │     │     │     │     │
  arr[0]=2: ────────────►
  arr[1]=3: ──────────────────────►
  arr[2]=1:             ─────►
  arr[3]=1:                   ─────►

  Optimal: 0 ──► 1 ──────────────► 4
                (2 jumps)

Key Takeaway

Minimum Jumps to Reach the End is a dynamic programming problem from the Fibonacci family where each state depends on earlier states. You keep an array holding the fewest jumps to reach each position, initialized to a sentinel meaning unreachable, with the start needing zero jumps. For each position, you look back at every earlier position whose reach covers it and take one more than the fewest jumps to the best such predecessor.

The direct double-loop DP is quadratic because every position scans its predecessors, which is perfectly acceptable for interview-sized inputs. The classic optimization tracks the farthest index reachable within the current jump's window and only increments the jump counter when forced to step beyond that window, bringing the work down to linear time with constant space. Knowing both approaches and explaining when each is appropriate is what makes the answer strong.

At the National Bank of India, Rajesh used this to model a settlement pipeline where each processing stage could skip ahead by up to a stage-specific number of stages. The operations team wanted the fewest hops from the first stage to the last to estimate the fastest possible completion time. The greedy window approach gave them an instant answer even for pipelines with hundreds of stages.

The senior-level insight is that the greedy approach is implicitly performing BFS level by level, where each "level" represents one jump. Being able to explain the BFS interpretation, the unreachability detection, and the path recovery extension shows an interviewer you understand the problem structure deeply.

Remember one sentence: minimum jumps is one plus the best predecessor's jumps via DP, optimized to linear time by tracking the farthest reachable window boundary.

---

Share
Use ← → arrow keys to navigate