We start at index 0, and at each index i, we can jump forward by up to nums[i] positions. The question is whether some sequence of jumps lands us at or beyond the last index.
We are not looking for the shortest path or the minimum number of jumps. We only need a yes or no answer, which means we never have to enumerate individual paths.
The only thing that can block us is a zero, or a run of values too small to carry us past a later zero. If the array contains no zeroes, every index is reachable and the answer is always true. The work is deciding whether the path can clear any zeroes that appear before the last index.
1 <= nums.length <= 10^4 → With n up to 10,000, an O(n^2) solution runs about 100 million operations in the worst case, which is on the edge of acceptable. An O(n) pass is well within limits.0 <= nums[i] <= 10^5 → Values are non-negative, so a jump never moves backward. Reachability only flows forward, and a value of 0 is the only entry that can stop forward progress.Define reachability directly: index i is reachable when some earlier reachable index j can jump to it, meaning j + nums[j] >= i. The answer is whether the last index is reachable.
Build a boolean array dp where dp[i] means index i is reachable from index 0. Set dp[0] = true because we start there. For every other index i, scan earlier indices j. If j is reachable (dp[j]) and can jump to i (j + nums[j] >= i), then dp[i] = true.
This computes the right answer but is slow: each index scans the indices before it.
dp of size n, initialized to false.dp[0] = true since we start at index 0.i from 1 to n - 1:j from 0 to i - 1:dp[j] is true and j + nums[j] >= i, set dp[i] = true and break.dp[n - 1].Loading animation...
i, we potentially scan all previous indices. In the worst case, every index checks almost every earlier index.n to track reachability.Storing reachability for every index is more information than the problem needs. The next approach replaces the whole array with a single number: the farthest index reachable so far.
Instead of asking "is index i reachable?" for every index, track one value: the farthest index reachable so far, maxReach.
Walk through the array left to right. At index i, if i <= maxReach then i is reachable, and from i we can jump as far as i + nums[i], so update maxReach = max(maxReach, i + nums[i]).
If i > maxReach at any point, index i is unreachable and no later index can help, so return false. If maxReach >= n - 1 at any point, the last index is reachable.
A jump from index i can land on any index from i + 1 up to i + nums[i], not only on i + nums[i]. So if index i is reachable, so is every index from 0 up to i + nums[i]. The set of reachable indices is therefore a contiguous prefix [0, maxReach] with no gaps, which is why a single number captures it.
This justifies the two checks. If i > maxReach, index i lies outside the reachable prefix and stays unreachable, because jumps only move forward and no later index can extend reach back to i. If maxReach >= n - 1, the last index lies inside the prefix and is reachable.
maxReach = 0 (we start at index 0, so that's the farthest we know we can reach).i from 0 to n - 1:i > maxReach, return false (we can't reach this index).maxReach = max(maxReach, i + nums[i]).maxReach >= n - 1, return true (we can reach the end).true (the loop completed, meaning we reached the last index).Loading animation...
maxReach.The next approach is also O(n) but reverses the direction. Instead of expanding reach forward from the start, it shrinks a goal backward from the last index.
Instead of tracking how far forward we can reach, reverse the problem. Place the goal at the last index, then scan backward. For each index, check whether it can reach the current goal, and if it can, move the goal to that index.
If index j can jump to the goal (j + nums[j] >= goal), then reaching j is enough to reach the end. The problem reduces to "can we reach index j?", and we repeat, moving the goal leftward each time it succeeds.
If the goal reaches index 0, the last index is reachable from the start.
The original question is "can index 0 reach index n-1?" Each goal move rewrites it as "can index 0 reach this closer goal?" The rewrite is valid because reachability is transitive: if index i can reach j and j can reach the old goal, then i can reach the old goal.
Moving the goal to the first qualifying index found going backward (the one nearest the goal) loses nothing. Any index further left that can reach the old goal can also reach this nearer index, since the gap to it is smaller. So if a valid path exists, the goal still walks all the way down to 0; if no index can cover some gap, the goal stalls above 0 and we return false.
goal = n - 1 (the last index).i = n - 2 down to 0:i + nums[i] >= goal, set goal = i (we can reach the old goal from here).true if goal == 0, false otherwise.Loading animation...
goal.