55–跳跃游戏(能否跳到最后):
给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
贪心法思路:
每一步确定下一步可到的范围,下一步所在范围确定下下一步的范围。当范围能完全覆盖数组,即可到达最后一个下标。
class Solution
{
public:
bool canJump(vector<int>& nums)
{
int n = nums.size();
int right = 0; // 当前能跳到的最远距离
// 若跳不到left,一定跳不到n-1,即若中间有任一点跳不到,一定跳不到最后
for(int left = 0; left > n; left++)
{
if(left > right)
{
return false;
}
// 更新当前最远位置
right = max(right, left + nums[left]);
}
return true;
}
};
45–题目–跳跃游戏(跳到最后的最小次数)
题目:
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。
每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
0 <= j <= nums[i]
i + j < n
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。
思路:
如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点。
-
可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离 不断更新。
-
如果从这个 起跳点 起跳叫做第 1 次 跳跃,那么从后面 3 个格子起跳 都 可以叫做第 2 次 跳跃。
-
所以,当一次 跳跃 结束时,从下一个格子开始,到现在 能跳到最远的距离,都 是下一次 跳跃 的 起跳点。
3.1. 对每一次 跳跃 用 for 循环来模拟。
3.2 跳完一次之后,更新下一次 起跳点 的范围。
3.3 在新的范围内跳,更新 能跳到最远的距离。 -
记录 跳跃 次数,如果跳到了终点,就得到了结果。
图解:
class Solution
{
public:
int jump(vector<int> &nums)
{
int times= 0;
int start = 0;
int end = 1;
while(end < nums.size())
{
int maxPose = 0;
for(int i = start; i<end; i++)
{
// 能跳到的最远距离
maxPose = max(maxPose, i+nums[i]);
}
start = end; // 下一次起跳点范围开始的格子
end = maxPose + 1; // 下一次起跳点范围结束的格子
times++; // 跳跃次数
}
return times;
}
};