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.)
最初的想法就是类似在Jump Game中的动态规划,忘记了那个题可以用贪心去做,结果超时,贴一下代码吧:
1 public int jump(int[] A) { 2 if(A==null||A.length==0){ 3 return 0; 4 } 5 int step[] = new int[A.length]; 6 for (int i = A.length - 1; i >= 0; i--) { 7 if (i == A.length - 1) { 8 step[i] = 0; 9 } else { 10 int min = Integer.MAX_VALUE; 11 for (int j = i + 1; j <= i + A[i] && j < A.length; j++) { 12 if(min>A[j]){ 13 min=A[j]; 14 } 15 } 16 step[i] = min + 1; 17 } 18 } 19 return step[0]; 20 }
这题可以用贪心去做,设Sij为从i到j最少需要的步数,则有Sij = min(Sik+Skj) (k从i+1到j-1)。设k为最优解的路线上经过的最后一个节点,设f[i]表示从小于等于i的任意位置开始走1步最远能够到达的位置。则有k为满足f[k] = j的最小的值。证明,若存在p<k使得f[p]=j,因为Sip<=Sik(后面证明),因此Sij = min(Sip+1,Sik+1) = Sip+1,因此p为最优解路线上最后一个节点,与k为最后一个节点矛盾,因此假设不成立,因此k是满足f[k] = j的最小的值。下面证明当p<k时,Sip<=Sik。设v为Sij最优路线上的最后一个节点,因此Sip = Siv+1,若从v节点最远可达k,则有Sik = Siv+1,因为v之前的节点不能到达p所以也不能到达k,若从v节点不可达k,则Sik>Siv+1,从上可知,Sip<=Sik。由此可知本题可以用贪心法求解。贪心的步骤就是每次找出能够到达的最远的点,若最远的点更新了,步长就加1.可得如下的代码:
1 public int jump(int[] A) { 2 int step = 0; 3 int last = 0; 4 int cur = 0; 5 for (int i = 0; i < A.length; ++i) { 6 if (i > last) { 7 last = cur; 8 ++step; 9 } 10 cur = cur > i + A[i] ? cur : i + A[i]; 11 } 12 return step; 13 }
Jump Game 的第一题参见 Jump Game