Jump Game II
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.)
SOLUTION 1:
參考:http://blog.csdn.net/fightforyourdream/article/details/14517453
我們可以使用貪心法來解決這個問題。
從后往前思考問題。以 des = len - 1反向思考。思考能到達它的最遠的距離是多少。
例子:
2 3 1 1 4
i = 1
上例子中index i = 1是達到4的最遠的距離。這時index i = 1 到4是最后一步的最優解,因為其它的解,如果跳到index = 2, 3 到達4為最后一步,那么倒數第二步既然可以到達 index = 2, 3 也可以到達index = 1,所以跳到index = 1步數會是一樣的。所以其它的解最好的情況也就是與從index = 1跳過去一樣而已。
而前面的點因為距離限制 ,有可能只能跳到index = 1,而不可以跳到index = 2, 3.所以 將倒數第二步設置在index = 1可以得到最多的解。

1 package Algorithms.greedy; 2 3 public class Jump { 4 public static void main(String[] strs) { 5 int[] A = {2, 3, 1, 1, 4}; 6 System.out.println(jump(A)); 7 } 8 9 public static int jump(int[] A) { 10 if (A == null || A.length == 0) { 11 return 0; 12 } 13 14 int len = A.length; 15 16 int sum = 0; 17 18 int des = len - 1; 19 while (des > 0) { // destination index 20 for (int i = 0; i < des; i++) { // 不斷向前移動dest 21 if (A[i] + i >= des) { // 說明從i位置能1步到達dest的位置 22 sum++; 23 des = i; // 更新dest位置,下一步就是計算要幾步能調到當前i的位置 24 //break; // 沒必要再繼續找,因為越早找到的i肯定越靠前,說明這一跳的距離越遠 25 // 這一行可以去掉, des = i,不符合for的條件,會自動break. 26 System.out.println("sum:" + sum); 27 System.out.println("des:" + des); 28 } 29 } 30 } 31 32 return sum; 33 } 34 }
SOLUTION 2:(2015.1.13 redo)
Leetcode增強test case之后,前面的算法不能通過,感謝http://fisherlei.blogspot.com/2012/12/leetcode-jump-ii.html的靈感:
[解題思路]
二指針問題,最大覆蓋區間。
從左往右掃描,維護一個覆蓋區間,每掃過一個元素,就重新計算覆蓋區間的邊界。比如,開始時區間[start, end], 遍歷A數組的過程中,不斷計算A[i]+i最大值(即從i坐標開始最大的覆蓋坐標),並設置這個最大覆蓋坐標為新的end邊界。而新的start邊界則為原end+1。不斷循環,直到end> n.

1 // solution 2: one pass greedy. 2 public int jump(int[] A) { 3 if (A == null || A.length == 0) { 4 return 0; 5 } 6 7 // bug: 8 /* 9 Input: [1] 10 Output: 1 11 Expected: 0 12 */ 13 if (A.length == 1) { 14 return 0; 15 } 16 17 int len = A.length; 18 19 int start = 0; 20 int end = 0; 21 22 int steps = 0; 23 while (end < len - 1) { 24 int max = 0; 25 steps++; 26 for (int i = start; i <= end; i++) { 27 max = Math.max(max, i + A[i]); 28 29 if (max >= len - 1) { 30 return steps; 31 } 32 } 33 34 start = end + 1; 35 end = max; 36 37 if (start > end) { 38 break; 39 } 40 } 41 42 return Integer.MAX_VALUE; 43 }
GITHUB:
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/greedy/Jump.java