The problem:
Given an array of non-negative integers, you are initially positioned at the first index of the array.Each element in the array represents your maximum jump length at that position.Determine if you are able to reach the last index.For example:A = [2,3,1,1,4], return true.A = [3,2,1,0,4], return false.
My analysis:
This question is very easy! You just need to understand clearly about the underlying invariant for reaching each element in the Array. The key idea: max_reach indicates the maximum position that could be reached now.At each position, we do following things:1. test if the current element could be reached by the previous elements(max_reach).if (max_reach < i) { return false;}2. if the current element could be reached, we check if we need to update the max_reach.iff max_reach < i + A[i], it indicates the max_reach element could be further.iff max_reach >= i + A[i], we need to do nothing.max_reach = Math.max(max_reach, i + A[i]);
My solution:
public class Solution { public boolean canJump(int[] A) { if (A == null || A.length == 1) return true; int max_reach = 0; for (int i = 0; i < A.length; i++) { if (max_reach < i) { return false; } else{ max_reach = Math.max(max_reach, i + A[i]); } } return true; }}
Problem 2:
Given an array of non-negative integers, you are initially positioned at the first index of the array.Each element in the array represents your maximum jump length at that position.Your goal is to reach the last index in the minimum number of jumps.For example:Given array A = [2,3,1,1,4]The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)
My analysis:
The idea behind this problem is easy.key idea: use a max_reach[] array to record the maximum position the elements(before and include element i) could reach.max_reach[i] : indicate how far we can reach from the elemenets(before and include element i). for (int i = 0; i < A.length; i++) { if (pre_max < i) return - 1; if (A[i] + i > pre_max) { max_reach[i] = A[i] + i; pre_max = A[i] + i; } else { max_reach[i] = pre_max; } }1. At each position, we have a reach range: [cur, max_reach[i]]. In the range, we would like to step farest(to quickly reach the last element). The range's farest reach is stored at max_reach[max_reach[i]], cause we only record the farest position we could reach at max_reach array.A = [2, 3, 1, 1, 4] max_reach = [2, 4, 4, 4, 8]At A[0], the reach range is [0, 2]. The farest position we could reach through the range is record at max_reach[2]. Note the invariant, it is very very interesting!We make our decison not based on the farest position(range) the current element could reach, but on the farest position(range) the current range could reach!How to get the range's information? we use max_reach[] array, it records the cultimative information in the array. !!!Range computation.2. There is a little pitfall we should take care, that is we only need to reach the last element! Don't continue the jump out of the array.while (temp_reach < A.length - 1) { temp_reach = max_reach[temp_reach]; count ++;}
My solution:
public class Solution { public int jump(int[] A) { if (A == null || A.length == 0) return -1; int[] max_reach = new int[A.length]; int pre_max = 0; int count = 0; int temp_reach; for (int i = 0; i < A.length; i++) { if (pre_max < i) //if we could not return - 1; if (A[i] + i > pre_max) { max_reach[i] = A[i] + i; pre_max = A[i] + i; } else { max_reach[i] = pre_max; } } temp_reach = 0; while (temp_reach < A.length - 1) { temp_reach = max_reach[temp_reach]; //except for last element, there is no possible: max_reach[temp_reach] = temp_reachcount ++; } return count; }}