跳跃游戏 II
给出一个非负整数数组,你最初定位在数组的第一个位置。
数组中的每个元素代表你在那个位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
样例
给出数组A = [2,3,1,1,4],最少到达数组最后一个位置的跳跃次数是2(从数组下标0跳一步到数组下标1,然后跳3步到数组的最后一个位置,一共跳跃2次)
标签
贪心 数组
(1)Java
public class JumpGame_II {
// Greedy 在DP超时情况下,只能试着用greedy了!AC
// Version 2 Greedy1
public static int jump2(int[] A) {
int jmp = 0;
int dest = A.length - 1; // destination index
while(dest != 0){ // 不断向前移动dest
for(int i = 0; i < dest; i++){
if(i + A[i] >= dest){ // 说明从i位置能1步到达dest的位置
dest = i; // 更新dest位置,下一步就是计算要几步能调到当前i的位置
jmp++;
break; // 没必要再继续找,因为越早找到的i肯定越靠前,说明这一跳的距离越远
}
}
}
return jmp;
}
// Version 2 Greedy2
public class Solution {
public int jump(int[] A) {
if (A == null || A.length == 0) {
return -1;
}
int start = 0, end = 0, jumps = 0;
while(end < A.length - 1){
int farthest = end;
for(int i = start; i <= end; i++){ // 本层循环不可漏写!!
if(i + A[i] > farthest){
farthest = i + A[i];
}
}
start = end + 1;
end = farthest;
jumps++;// 跳出说明end >= A.length - 1,此后无需再jump++
}
return jumps;
}
}
// 动归
// version 1: Dynamic Programming
// 这个方法,复杂度是 O(n^2),会超时,但是依然需要掌握。
class JumpGame01 {
public int jump(int[] A) {
// state
int[] steps = new int[A.length];
// initialize
steps[0] = 0;
for (int i = 1; i < A.length; i++) {
steps[i] = Integer.MAX_VALUE;
}
// function
for (int i = 1; i < A.length; i++) {
for (int j = 0; j < i; j++) {
if (steps[j] != Integer.MAX_VALUE && j + A[j] >= i) {
steps[i] = Math.min(steps[i], steps[j] + 1);
}
}
}
// answer
return steps[A.length - 1];
}
}
(2)C++
① Version 1
class JumpGameII{
public:
int jump(vector<int> &nums){
if(nums.size() <= 1){// 若数组长度<= 1 则不用跳跃,返回0
return 0;
}
int cur_max_i= nums[0];
int pre_max_i = nums[0];
int jump_min = 1;// 最少跳跃次数
for(int i = 0; i < nums.size(); i++){
if(i > cur_max_i){//❤️ 贪心思想: 若无法再向前移动了,才进行跳跃(如: 走到i+1了,而cur_max_i还只更新到i)
jump_min++;
cur_max_i = pre_max_i;// 即更新当前可到达的最远位置
}
if(pre_max_i < i + nums[i]){ // i + nums[i] 即为index[i],即最远跳至的下标
pre_max_i = i + nums[i];
}
}//❤️ 注意以上两if不可颠倒!
return jump_min;
}
};
int main()
{
vector<int> nums;
nums.push_back(2);
nums.push_back(3);
nums.push_back(1);
nums.push_back(1);
nums.push_back(4);
JumpGameII jg2;
cout << jg2.jump(nums) << endl;
return 0;
}
其他:
① Greedy
② Two Pointers