题目:
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
class Solution {
public:
/********************************法一:;**********************************/
// int jump(vector<int>& nums)
// {
// if(nums.size() <= 1)
// {
// return 0;
// }
// int cur = 0; // 当前覆盖最远距离下标 注意这个是赋初值为 0 ,而不是 nums[0]
// int next = 0; // 下一步覆盖最远距离下标
// int result = 0; // 记录步数
// // 这个for循环的循环控制条件不是 cur 而是 nums.size()
// // 因为上一题的for里面有 return,符合条件直接跳出循环并结束这个函数
// // 而这里是没有 return 的,所以要设定遍历整个数组后结束循环
// for(int i = 0; i < nums.size(); i++)
// {
// // 这里要更新的不是 cur ,而是 next,使 next 在cur的范围内是最大值
// next = max(next, i + nums[i]);
// // 这里相当于在遍历 cur 范围内的 jump 步数,遍历完当前cur,就步数加 1,更新下一个 cur
// if(i == cur)
// {
// // 判断当前覆盖最远距离下标不是终点,如果不是还需要加加运算,如果是则无需加加,直接 break
// if(cur != nums.size() - 1)
// {
// result++;
// cur = next;
// // 判断下一步的覆盖范围是否包括终点,如果包括则直接返回,此时步数也是满足的
// if(next >= nums.size() - 1)
// {
// break;
// }
// }
// else
// {
// break;
// }
// }
// }
// return result;
// }
/**************************法二::***************************/
// 方法二与方法一是一样的贪心思想,其精髓就是要理解,for循环的终止条件处是当下标 i 到达 nums.size()-2 即可
// 对于方法二,当 i 已经到达了倒数第二个元素,且 i 还小于 cur,
// 就说明此时 cur 的范围至少是包括着 倒数第一个元素的,甚至更大
int jump(vector<int>& nums)
{
// if(nums.size() <= 1)
// {
// return 0;
// }
int result = 0;
int cur = 0;
int next = 0;
for(int i = 0; i < nums.size() - 1; i++)
{
next = max(next, i + nums[i]);
// 犯错!!!!!!if语句中的 双等于 写成了 单等于
if(i == cur)
{
result++;
cur = next;
}
}
return result;
}
};