这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战
前言
力扣第四十五题 跳跃游戏 II 如下所示:
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
提示:
1 <= nums.length <= 1040 <= nums[i] <= 1000
一、思路
这道题我刚开始以为就是使用
贪心算法,在可达到的范围内取一个较大的值,一直到数组的末尾。直到被测试用例击败无数次的我 tnt
这道题的核心就是要明白:下一个位置为:已走的距离+将走的距离最大化
首先我们看一下右面这个例子:nums = [4, 3, 1, 1, 2, 1, 1]
你知道正确的跳跃路径是什么吗?答案为 4 -> 2 -> 1
为什么第一次跳跃不选择范围内较大的值 nums[1] = 3 呢?
- 因为如果选择
4 -> 3这个路径的话,已走的距离为1-0 = 1,将走的距离为nums[1] = 3,和为1+3 = 4 - 而选择
4 -> 2这个路径,已走的距离为4-0 = 4,将走的距离为nums[4] = 2,和为4+2 = 6 - 显然选择
4 -> 2可以走的更远!
举个例子
此处仍以上面的 nums = [4, 3, 1, 1, 2, 1, 1] 作为例子
i=1时,可选择的范围为nums[1] ~ nums[4],经过距离最大化的筛选,最终选择nums[4] = 2,跳跃路径为4 -> 2- 来到下一个起始位置,
i=4,可选择的范围为nums[5] ~ nums[6],经过距离最大化的筛选,最终选择nums[6] = 1,跳跃路径为4 -> 2 -> 1 - 返回选择的次数
3即可
二、实现
实现代码
实现代码与思路保持一致
/**
* 贪心算法
* @param nums
* @return
*/
public int jump(int[] nums) {
if (nums.length == 1)
return 0;
int ret = 0;
int len = nums.length;
// 从前往后
out:for (int i=0; i<len;) {
int n = nums[i];
int next = -1; // 下一个位置为:已走的距离+将走的距离最大化
for (int j=i+1; j<n+i+1; j++) {
if (j == len -1) {
ret ++;
break out;
}
if (next == -1) {
next = j;
continue;
}
int currentDistance = (j-i) + nums[j]; // 当前距离和
int nextDistance = (next-i) + nums[next]; // 下一个距离和
if (currentDistance > nextDistance) {
next = j;
}
}
ret ++;
i = next;
}
return ret;
}
测试代码
public static void main(String[] args) {
int[] nums = {4,1,1,3,1,1,1};
new Number45().jump(nums);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥