这道题和“跳跃游戏1”不同,跳跃游戏1是为了看能否到达终点,所以每次都尽可能往能到更远的地方跳,而这道题不同,这道题是确定了我们总是可以到达终点,所以不用想会不会跳不到终点的问题,我们需要尽可能少的跳,那么问题的关键就是在什么时候跳。
假设:0....i -2 , i-1, i , i+1, i+2, i+3 , .....有这些位置,我们可以从0跳到的最远位置是i,从 i-2能跳到 i+3, 而从 i 最多只能到i+1。
那么我们在从0到 i 的时候什么时候跳呢,如果在i-2跳了,万一 i-1可以跳更远,如果i-2不跳,i-1 ,i 又跳不远。。
所以我们需要记录下一跳能到的最远位置 pre_max_position。而当前要到的最远位置是cur_max_position。
我们在不得不跳的时候再跳
遍历Num数组,从0到 i (在这里, i 假设是0能跳到的最远位置cur_max_position)的过程中,看0到i 之间的位置哪个能跳到更远,记录为pre_max_position,然后到了 i ,更新cur_max_position = pre_max_position,然后跳的次数加1
所以这样其实也可以记录下跳的路径,我们实际要跳出最少次数的话,并不是真正的在cur_max_position这个位置跳的,而是在产生 pre_max_position的位置跳的,并且是跳到 pre_max_position之前的能跳到更远位置的位置
class Solution {
public:
int jump(vector<int>& nums) {
if(nums.size()<2)
return 0;
int cur_max_position = nums[0];//记录当前要到达的最远位置
int pre_max_position = nums[0];//在到达最远位置的路上,记录的能到达的最远位置
int jump = 1;//至少要跳一次,所以初始为1
for(int i =1;i<nums.size();++i)
{
if(i+nums[i] > pre_max_position)
pre_max_position = i+nums[i];
if(i == cur_max_position && i!=nums.size()-1)//当i已经到了终点的话,就不用再跳了。没到终点的话,而且又是cur_max_position的话,就更新
{
jump++;
cur_max_position = pre_max_position;
}
}
return jump;
}
};