“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”
一、题目描述
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
提示:
1 <= nums.length <= 1040 <= nums[i] <= 1000
二、思路分析
这道题是 55. 跳跃游戏(中等) 的进阶。题目明确告诉我们:一定能够跳到数组的最后一个元素,要我们以尽可能少的次数跳到最后一个元素。
我们以 nums = [2,3,1,1,4] 来模拟一下跳跃过程:
遍历 nums 数组,首先走到 2 ,此时可以跳跃 2 步的距离,此时发现后面两步中,最远可以跳 3 步,因此选择先跳 1 步到 3 的位置,然后再跳 3 步直接到数组的最后一个元素。
然而这只是我们人为的判断,计算机在未遍历到后面的元素时是不知道可以跳多远的,更不可能选择最佳的跳跃方案。 但是结合模拟过程,我们思考出如下方案:
- 首先,定义
end表示跳跃到的位置,distance表示最远的跳跃距离(以数组第一个元素为起点),count表示跳跃的次数。 - 然后,遍历
nums数组,更新distance为最远的跳跃距离,(根据当前元素的值跳跃,值为几就跳几步,但并不是真的跳,而是在大脑中模拟这个过程),判断end == i(表示遍历到跳跃的位置了)是否为真,不是的话就继续遍历,是的话就说明还未到达最后一个元素,还要接着跳,因此count++,并且跳distance步(要跳当然就跳最远的距离,即更新end = distance,同样不是真的跳,而是在大脑中模拟这个过程)。
如果遍历到最后依然
end != distance,说明已经跳的足够远了,距离超出了数组的长度,也就无需count++了。
三、AC 代码
class Solution {
public:
int jump(vector<int>& nums) {
int end = 0, distance = 0;
int count = 0;
for (int i = 0; i < nums.size() - 1; i++) {
distance = max(distance, nums[i] + i);
if (end == i) {
count++;
end = distance;
}
}
return count;
}
};