C++算法练习day73——45.跳跃游戏2
题目来源:. - 力扣(LeetCode)
题目思路分析
题目:给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。
思路:
- 贪心算法:这个问题可以通过贪心算法来解决。贪心算法的核心思想是每一步都选择当前最优解,从而希望这样的局部最优解能够导致全局最优解。
- 维护边界:我们需要维护两个关键的边界:
right_point
:表示在当前跳跃能力下,能够到达的最远位置。max_point
:在遍历过程中,不断更新在当前位置i
下,通过一次跳跃能够到达的最远位置。
- 跳跃次数:每当遍历到
right_point
时,表示需要进行一次新的跳跃,此时更新right_point
为max_point
,并增加跳跃次数。 - 提前结束:如果
right_point
已经能够到达或超过数组的最后一个位置,则无需继续遍历,直接返回当前跳跃次数。
代码:
#include <vector>
#include <algorithm>
class Solution {
public:
int jump(vector<int>& nums) {
int step = 0; // 记录跳跃次数
int max_point = 0; // 在当前遍历范围内,通过一次跳跃能够到达的最远位置
int right_point = 0; // 当前跳跃能力下,能够到达的最远位置
for (int i = 0; i < nums.size() - 1; i++) { // 遍历到倒数第二个元素
int point = i + nums[i]; // 计算从当前位置 i 跳跃后能够到达的最远位置
max_point = max(max_point, point); // 更新 max_point
// 当遍历到当前跳跃能力的边界时
if (i == right_point) {
step++; // 需要进行一次新的跳跃
right_point = max_point; // 更新 right_point 为新的最远边界
// 如果新的最远边界已经能够到达或超过数组的最后一个位置,则结束循环
if (right_point >= nums.size() - 1) {
break;
}
}
}
return step; // 返回跳跃次数
}
};
知识点摘要
- 贪心算法:每一步都选择当前最优解,从而希望这样的局部最优解能够导致全局最优解。
- 边界维护:通过维护两个边界(
right_point
和max_point
)来跟踪当前跳跃能力和能够到达的最远位置。 - 算法复杂度:时间复杂度为 O(n),因为我们只遍历了一次数组;空间复杂度为 O(1),因为我们只使用了几个变量来存储中间结果。
这个问题是一个典型的贪心算法应用实例,通过维护两个关键的边界(right_point
和 max_point
),我们可以有效地计算出到达数组最后一个位置所需的最少跳跃次数。贪心算法的核心在于每一步都选择当前最优解,从而逐步逼近全局最优解。这种方法不仅简洁高效,而且易于理解和实现。通过这个问题,我们可以更深入地理解贪心算法的应用场景和实现方法。