题目描述
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
说明:
假设你总是可以到达数组的最后一个位置。
解法
贪心算法
贪心算法的特征
1、贪心选择性质
一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择。这就是贪心选择性质。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
2、最优子结构性质
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心法求解的关键所在。在实际应用中,至于什么问题具有什么样的贪心选择性质是不确定的,需要具体问题具体分析
分析本题
我们要找出达到数组最后一个位置的下标最少的跳跃次数,显然是求最优解的问题,那么我们思考🤔子问题,就是我在每次跳跃的位置,显然也是求最优解。
这个时候我们满足了求最优解和子问题的最优解,那么想一个问题:我在0为下标的位置,可以跳两个位置,但是很明显跳到下标为1的位置更好。所以我在当前位置跳跃的最优解就是我在当前位置可以选择跳到的下个位置的最远距离,即每次我们都跳跃到a,a的数值最大。
上述案例解
下标0 - 可以跳到1和2,而我们选择1,因为1可以跳的更远
代码
class Solution {
public int jump(int[] nums) {
int maxLength = 0;
int end = 0;
int step = 0;
for(int i = 0; i<nums.length-1; i++){
// 我们每次循环都求可跳跃位置下标的最大值,这就是求最优解的过程
maxLength = Math.max(maxLength,i+nums[i]);
// 当循环索引等于end的时候表明我们已经遍历完了这个位置的所有跳跃可能性,并找到了最优解
if(i==end){
end = maxLength;
step++;
}
}
return step;
}
}