给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
示例一:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例二:
输入: nums = [2,3,0,1,4]
输出: 2
总体思想是,在当前节点可以到达的所有位置中,选择可以到达最远位置的节点。
1.贪心
根据错误的输出不断调整程序。
(1)当前位置i<nums.size()-1时才继续跳跃,如果i=nums.size()-1,说明当前位置是终点。
(2)如果当前位置到达的下一个位置(i+j)已经是终点,直接返回结果。
(3)如果到达的下一个位置跳跃长度是0,不选择该节点。
class Solution {
public:
int jump(vector<int>& nums) {
if(nums.size()==1){
return 0;
}
int i=0,res=0;
while(i<nums.size()-1){ //i=nums.size()-1时,到达最后一个位置
res++;
int maxj=1;
int maxd=0;
for(int j=1;j<=nums[i] && i+j<nums.size();j++){ //遍历可以从i到达的每一个地方
if(i+j>=nums.size()-1){ //如果可以直接到达终点,返回结果
return res;
}
if(nums[i+j]==0){
continue; //不到达跳跃长度是0的地方
}
if(nums[i+j]+j>maxd){ //如果i+j到达的位置更远,选择i+j为下一次到达的地方
maxd=nums[i+j]+j;
maxj=j;
}
}
//cout<<"i:"<<i;
i+=maxj;
//cout<<" nexti:"<<i<<" maxj:"<<maxj<<endl;
}
return res;
}
};
class Solution {
public:
int jump(vector<int>& nums) {
int maxpos=0; //目前能跳到的最远的位置
int end=0; //上次跳跃到的最右边的边界,下次起跳的地方
int step=0;
for(int i=0;i<nums.size()-1;i++){
maxpos=max(maxpos,nums[i]+i); //更新能到达的最远的位置
if(maxpos>=i){ //如果当前位置还在边界内
maxpos=max(maxpos,nums[i]+i);
}
if(i==end){
end=maxpos;
step++;
}
}
return step;
}
};