先回顾一下跳跃游戏1(Leetcode 55):
class Solution {
public boolean canJump(int[] nums) {
if(nums[0] == 0 && nums.length ==1) return true;
if(nums[0] == 0 && nums.length > 1) return false;
int n = nums.length;
int count = 1; //count代表到达当前设定点需要走几步
//从倒数第二个数向前判断
for(int i = n - 2;i>=0;i--)
if(nums[i] >= count) { //意味着从i点可以直接到设定点
count = 1; //这时即可看作考虑有没有路径可以到达i点,前一个点至少需要走1步
continue;
} else count++; //如果当前点到不了,它前面的点至少需要满足count++才可以到达
if(count == 1) return true;
else return false;
}
}
跳跃游戏2:
贪心算法,从起始点开始,找到它可以到达的位置区间,从这个位置区间中找到能到达的最远的,作为下一次搜索的开头。
举例:
2,3,1,1,4
对每一个点,它能到达的区间是[i+1,i+nums[i]],第一个点2,他可以到达1,2位置,从位置2只能到达位置3,从位置1可以直接到结尾位置5,两步结束。假如有后续,会继续考察位置4,5。
class Solution {
public int jump(int[] nums) {
int n = nums.length;
if(n < 2) return 0;
int step = 1; //计步
int begin = 0; //初始从0位置开始往后算
int nextReach = nums[0]; //存储能够到达的最大位置
int tmp = 0; //中间变量存储在区间内计算出的可达位置,用于更新最大值
while(begin < n) {
if(nextReach >= n-1) return step;
for(int i = begin + 1; i <= nextReach; i++) {
if(i + nums[i] > tmp) tmp = i + nums[i]; //能到达更远的位置
}
begin = nextReach; //上一次的区间终点作为此次起点
nextReach = tmp; //此次区间终点
step++;
}
return step;
}
}