Jump Game
Problem
You are given an integer array nums where each element nums[i] indicates your maximum jump length at that position.
Return true if you can reach the last index starting from index 0, or false otherwise.
Examples
Example 1:
Input: nums = [1,2,0,1,0]
Output: true
Explanation: First jump from index 0 to 1, then from index 1 to 3, and lastly from index 3 to 4.
Example 2:
Input: nums = [1,2,1,0,1]
Output: false
Constraints
1 <= nums.length <= 10000 <= nums[i] <= 1000
You should aim for a solution with O(n) time and O(1) space, where n is the size of input array.
Solution
The DFS branches over all possible jumps, but the only information that matters is the farthest reachable index; since reachable positions form a contiguous interval and farther reach is never worse, the branching state can be collapsed into a greedy frontier.
class Solution {
public:
bool canJump(const vector<int>& nums) {
int farthest = 0;
for (int i = 0; i < nums.size(); ++i) {
// We are at an index that is over how far we can actually get to
if (i > farthest) { return false; }
// From this reachable index, extend how far we can get
farthest = std::max(farthest, i + nums[i]);
if (farthest >= nums.size()) {
return true;
}
}
return true;
}
};DFS asks whether we can jump to the end, starting at the current index. This is an O(n^2) solution
class Solution {
public:
bool canJump(const vector<int>& nums) {
// Whether we can reach end from index
std::vector<int> memo(nums.size(), -1);
std::function<bool(int)> dfs;
dfs = [&](int idx) -> bool {
// Ran off the end
if (idx >= nums.size()) { return false; }
// Reached the end
if (idx == nums.size() - 1) { return true; }
// We've seen this one before
if (memo[idx] != -1) { return memo[idx]; }
// iterate over the amount of jumps we can do
for (int i = 1; i <= nums[idx]; ++i) {
if (dfs(idx + i)) {
memo[idx] = true;
return true;
}
}
// None of the jumps reached, false
memo[idx] = false;
return false;
};
return dfs(0);
}
};