题目描述
45. 跳跃游戏 II
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
思路描述
// 以最小的步数得到最大的覆盖范围(即数组的最后位置)
// 思路是 用局部最优得到全局最优,即当前的每一步都尽量走最大的覆盖范围,最后就可以达到整体最优
// 这里的关键是 怎样去选择下一跳在覆盖范围内的点???肯定不能直接选最远的,而应该每次循环在所内覆盖到的范围内进行
// 所以考虑维护两个最大的 覆盖范围,
// 1)此次能够跳跃的边界 2)当前位置的最大覆盖范围
有点动态规划加贪心的意思。
class Solution {
public:
int jump(vector<int>& nums) {
int res_min = 0; // 最小的跳跃步数
int end = 0; // 即当前位置可以到达的边界值,到达边界跳数就需要+1
int longest_distance = 0; // 当前位置的最远覆盖范围
for(int i=0; i<nums.size(); ++i){
longest_distance = max(longest_distance, nums[i]+i); // 每次循环开始都更新下一个位置的最远覆盖范围
// 其实是在用longest_distance来考虑最远的覆盖范围,而end这个边界来控制进行判断的时机
if(i == end){ // 当此时下标到达了能覆盖范围的边界,则需要继续跳,即跳数+1,当然+1前还需要判断此时是不是已经到达了最后的位置
if(end != nums.size()-1){ // 若当前最远的覆盖下标不是最后一个位置
++res_min; // 一定需要再跳一步
end = longest_distance; // 因为跳到了下一步,所以更新最新的覆盖范围边界
if(longest_distance >= nums.size()-1) break; // 每次到达了覆盖的边界,都要判断下下一个最远覆盖是不是超过了数组最后元素位置。
}
else break;// 等于即:覆盖范围到达了最后的位置,直接返回即可,也不需要增加步数
}
}
return res_min;
}
};
本文介绍了一种解决跳跃游戏II问题的方法,通过维护两个最大覆盖范围,采用动态规划与贪心策略相结合的方式,实现了寻找最少跳跃次数到达数组末尾的目标。
3964

被折叠的 条评论
为什么被折叠?



