Given an array where nums[i] is the max jump length from index i, find the minimum number of jumps to reach the last index. The greedy insight: treat each jump as a BFS level — track the farthest you can reach and count a new jump whenever you exhaust the current level.
You're given nums = [2,3,1,1,4]. From index 0 you can jump up to 2 steps (land at index 1 or 2). Find the fewest jumps to reach the last index (4). The answer is 2: jump from index 0 to 1 (value 3), then jump from 1 to 4. The problem guarantees you can always reach the end.
farthest (max index reachable from any position seen so far) and currentEnd (end of the current level). When i hits currentEnd, you must jump — increment the counter and advance currentEnd = farthest. No queue, no visited set — just two integers.jumps = 0, currentEnd = 0, farthest = 0. These represent: how many jumps taken, the end of the current BFS level, and the best reach seen in this level.farthest = max(farthest, i + nums[i]). We stop before the last index because standing there already means we're done — no extra jump needed.i === currentEndwe've exhausted everything reachable on the current level. Increment jumps and set currentEnd = farthest to open the next level.jumps holds the minimum count.n - 2 (exclusive of the last index), not n - 1. When i === n - 1we're already at the destination — counting a jump there would over-count by one. Many implementations fix this with a special-case check; the cleaner approach is simply stopping the loop one index early.dp[i] = min(dp[j] + 1) for all reachable j — nested loop.The greedy approach works because expanding the farthest reach is always optimal: taking a shorter jump now can never help if a longer jump was available at the same cost. This is the hallmark of a locally optimal = globally optimal greedy argument.
farthest >= n-1), Jump Game III (BFS with a queue — bidirectional), Minimum Number of Taps to Open to Water a Garden(same greedy on intervals), and any "minimum steps to reach end" interval-coverage problem.[2, 3, 1, 1, 4]. We scan left to right, tracking farthest (max reach so far) and currentEnd(end of current jump's range). Jump count starts at 0.1function jump(nums: number[]): number {2▶ let jumps = 0;3▶ let currentEnd = 0; // boundary of the current "level" (BFS frontier)4▶ let farthest = 0; // best reach seen within this level56 for (let i = 0; i < nums.length - 1; i++) {7 farthest = Math.max(farthest, i + nums[i]);89 if (i === currentEnd) { // exhausted current level — must jump10 jumps++;11 currentEnd = farthest; // next level ends at the best reach12 }13 }14 return jumps;15}
function jump(nums: number[]): number {
let jumps = 0;
let currentEnd = 0; // boundary of the current "level" (BFS frontier)
let farthest = 0; // best reach seen within this level
for (let i = 0; i < nums.length - 1; i++) {
farthest = Math.max(farthest, i + nums[i]);
if (i === currentEnd) { // exhausted current level — must jump
jumps++;
currentEnd = farthest; // next level ends at the best reach
}
}
return jumps;
}jumpscounts how many jumps we've committed to. currentEnd marks the rightmost index we can reach with the jumps taken so far (starts at 0— "we haven't jumped yet"). farthesttracks the best reach we've seen while scanning the current level.jumps++ when currentEnd reaches it, over-counting by one.i + nums[i] is the furthest index reachable in a single jump from position i. We greedily keep the maximum across all positions scanned in the current BFS level.i equals currentEndwe've exhausted the current frontier — every index reachable in k jumps has been examined. We must use another jump, so we increment jumps and advance currentEnd to farthest, opening the next BFS level.n-2; jumps now holds the exact minimum number of jumps to reach the last index.n - 1 indices; each index is visited exactly once. O(1) space — three integer variables regardless of input size.parent[] array tracking which index you jumped from at each level transition; backtrack from n-1 after the loop.farthest >= n-1 after the loop, or detect when currentEnd stops advancing (stuck on a zero).dp[i] = min(dp[j] + 1) for all j that can reach i. O(n²) time and O(n) space — correct but too slow for large inputs.n=1) returns 0 — already at destination. All-zero array except the first index (value 0 everywhere) is impossible by the problem guarantee, so no need to handle it.function jump(nums: number[]): number {
let jumps = 0;
let currentEnd = 0; // boundary of the current "level" (BFS frontier)
let farthest = 0; // best reach seen within this level
for (let i = 0; i < nums.length - 1; i++) {
farthest = Math.max(farthest, i + nums[i]);
if (i === currentEnd) { // exhausted current level — must jump
jumps++;
currentEnd = farthest; // next level ends at the best reach
}
}
return jumps;
}n - 1 indices; each index is visited exactly once. O(1) space — three integer variables regardless of input size.Let dp[i] be the fewest jumps to reach index i. From each reachable i, relax every index in its jump range. The answer is dp[n-1].
function jump(nums: number[]): number {
const n = nums.length;
const dp = new Array<number>(n).fill(Infinity);
dp[0] = 0;
for (let i = 0; i < n; i++) {
if (dp[i] === Infinity) continue; // unreachable
const limit = Math.min(i + nums[i], n - 1);
for (let j = i + 1; j <= limit; j++) {
dp[j] = Math.min(dp[j], dp[i] + 1);
}
}
return dp[n - 1];
}| "minimum jumps to reach end" | greedy BFS-by-levels (farthest + currentEnd) |
| "minimum steps to cover an interval" | greedy interval-coverage / jump game pattern |
| each position has a max reach | i + nums[i] for local reach, max across level for global |
| BFS on implicit graph with O(1) space | level boundary trick — no queue needed |
let jumps = 0;
let currentEnd = 0;
let farthest = 0;
for (let i = 0; i < nums.length - 1; i++) {
farthest = Math.max(farthest, i + nums[i]);
if (i === currentEnd) {
jumps++;
currentEnd = farthest;
}
}
return jumps;jumps = jumps committed; currentEnd = rightmost index reachable in current jump budget; farthest = best reach seen while scanning this level.nums = [2,3,1,1,4], what is the minimum number of jumps?i, we update farthest = Math.max(farthest, i + nums[i]). What does i + nums[i] represent?nums = [1,1,1,1]. How many jumps are taken and how many jumps++ events fire?