Jump Game
Question (LC.55)
Given an array of non-negative integers, each element represents the max length you can jump at that position. Starting from the first index, can you reach the end?
Example
I: A = [2,3,1,1,4]
O: True
I: A = [3,2,1,0,4]
O: there is a 0 on the index 3 and no way to jump over it. FalseAnalysis
First thing to do is drawing out the jump DAG. Having a concrete picture is much easier way to think than looking at the numbers themselves. Essentially, we want to know whether there is a path from the first node to the last node. Intuitively, we can use DFS to test if the last node is reachable from the first node.
DFS Approach
public boolean canJump(int[] nums) {
if (nums == null || nums.length == 0) {
return true;
}
int[] flag = new int[1];
jumpHelper(nums, 0, flag);
return flag[0] == 1;
}
private void jumpHelper(int[] nums, int currentPos, int[] flag) {
if (flag[0] == 1) {
return;
}
if (currentPos == nums.length - 1) {
flag[0] = 1;
return;
}
for (int i = 1; i <= nums[currentPos]; i++) {
jumpHelper(nums, currentPos + i, flag);
}
}DP Approach
Then we observe there can overlapping paths. For example, if we already know a path is not leading to the destination, we don't have to recursively visit it again.
DP Code
Greedy Approach
Jump Game II (LC.45)
The objective now is to minimize the number of steps to reach the last index.
Example
What if there's a gap? For instance [2,1,0,0,5]. Assume that you can always reach the last index.
Analysis
Obviously, we can do an exhaustive search from the last index to find all possible paths and maintain a global min. But then many paths would be revisited many times. We can use memoization or tabulation to avoid recomputing the same path.
DP Approach
DP Code
Time & Space Complexity
The DP solution gives O(n^2) time and uses O(n) extra space. However, it results in time limit exceeded on LC. This begs for another approach that is linear time.
Greedy Approach
Exchange argument
Switch to the pos before and can jump to the current pos
Keep the rest of the solution optimal
Search backward from current pos to find the leftest pos that can jump to the current position then look left again from that leftest position
Time O(n^2) Space O(1)
Conclusion
We can certainly use memoization for any DP question. But if the we can easily figure out the topological ordering, then we can also do tabulation which saves the call stack.
Last updated