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.)
这道题的意思是给定一个数组,然后数组中的每个数字代表的就是该位置上可以移动的位置大小,例如说,第一个数2代表可以移动两位,即移动到第一个1的地方(也可以移动到3处),然后3代表最大可以移动到4,即最后一位。然后求出移动到最后一位的最小步数,例子中就是2 ->3 -> 4即两步。
刚开始的想法是,取一个数组,然后求出到达每一位的最小步数,然而超时了
public class Solution { public static int jump(int[] nums){ if( nums.length == 1) return 0; int len = nums.length; int[] result = new int[len]; for( int i = 0; i<len;i++){ if( i+nums[i] >= len-1){ return result[i]+1; } int pos = i; int num = result[i] + 1; for( int j = 0; j<=nums[i];j++,pos++){ if(result[pos] == 0) result[pos] = num; } } return result[len-1]; } }
用错误的数组run code一下,看上去答案应该是正确的,不过是414ms超时,由此发现之前的算法果然太暴力。
于是,类似于递归,从前到后遍历,遇到的第一个i+nums[i]将作为新的所求目标位置,并且将result+1,直到所求位置pos到达0或者1为止。结果1ms,但是仍然超时。这到底是什么我也并不知道。。。。。
代码如下:
public class Solution { public static int jump(int[] nums){ int len = nums.length; int result = 0, pos = len-1; while(true){ if( pos == 0) return result; else if( pos == 1) return result+1; for( int i = 0; i<len ; i++){ if( i + nums[i] >= pos){ result++; pos = i; break; } } } } }
然后参考了其他人的答案,发现一般会使用BFS(广度/宽度优先搜索便利)或者是greedy(贪心算法)来进行解答。但是这两者是差不多的。
然后我选择了贪心算法。(这里有一个很重要的前提是一定能够走到)
这个结果是2ms,但是就刚才超时的那组测试数据,运行时间也显示的是1ms,所以就对于为什么刚才的代码超时又了困惑,看了leetcode上的讨论也没有找到对应的解决方法。
1.这里就是记录当前能走到的最远距离以及步数(maxlen和result),另外还有当前步数(result)能走到的最远距离(prepos)。
2.到下一个数字的时候,下一个数字能到达的最大距离当然是 newlen = i+nums[i] ,然后newlen与maxlen对比,如果当前数字的最远距离比之前所计算的距离要远。
2.1 然后当前位置 i 再与 当前步数 result 的最大距离 prepos 进行对比,如果超过了 prepos 那么 result++, 并且 prepos 置为 当前的最大距离。
2.2 之后将最大距离置为newlen。同时可以进行判断,如果maxlen达到了len-1,那么就意味着可以达到最后。
public class Solution { public static int jump(int[] nums){ int len = nums.length; if( len < 2 ) return 0; int maxlen = nums[0]; int newlen = 0; int result = 1, prepos = 0; if (maxlen >= len-1) return result; for( int i =1;i<len;i++){ newlen = i + nums[i]; if( newlen > maxlen){ if( prepos < i ){ prepos = maxlen; result++; } maxlen = newlen; if( maxlen >= len-1 ) return result; } } return result; } }