Algorithm
-
-
- [🎯 问题描述](#🎯 问题描述)
- [🛠️ 思路与方法](#🛠️ 思路与方法)
- [1. 贪心算法(Greedy Algorithm)](#1. 贪心算法(Greedy Algorithm))
- [2. 时间与空间复杂度](#2. 时间与空间复杂度)
- [📚 C++ 实现](#📚 C++ 实现)
- [🧠 逐步解释](#🧠 逐步解释)
- [✅ 示例解释](#✅ 示例解释)
- [⏱️ 复杂度分析](#⏱️ 复杂度分析)
- [🧩 小结](#🧩 小结)
-
🎯 问题描述
给定一个非负整数数组 nums
,数组中的每个元素代表你在该位置可以跳跃的最大长度。最初你位于数组的第一个下标,判断你是否能够到达最后一个下标。如果可以到达,返回 true
,否则返回 false
。
🛠️ 思路与方法
1. 贪心算法(Greedy Algorithm)
这个问题的核心是检查是否可以通过跳跃到达数组的最后一个元素。我们可以通过贪心算法来解决该问题。
核心思想:
- 通过一个变量
farthest
来记录能到达的最远位置。 - 遍历数组中的每个元素,在每个位置我们能跳跃的最大长度是
nums[i]
,那么当前能到达的最远位置为farthest = max(farthest, i + nums[i])
。 - 如果在某个位置
i
,farthest
已经不能再前进了,即farthest <= i
,说明我们无法继续跳跃到更远的地方,返回false
。 - 如果在遍历过程中,
farthest
达到或超过了最后一个下标n-1
,则可以到达最后一个下标,返回true
。
2. 时间与空间复杂度
- 时间复杂度:O(n),我们只需要遍历一次数组。
- 空间复杂度:O(1),我们只使用常数空间来存储变量。
📚 C++ 实现
cpp
#include <vector>
#include <iostream>
using namespace std;
class Solution {
public:
bool canJump(vector<int>& nums) {
int farthest = 0; // 记录最远可以到达的下标
int n = nums.size();
for (int i = 0; i < n; ++i) {
if (i > farthest) {
// 如果当前位置 i 已经超出了能到达的最远位置,说明无法到达
return false;
}
// 更新最远可以到达的位置
farthest = max(farthest, i + nums[i]);
// 如果最远位置已经到达或超过最后一个下标,说明可以到达
if (farthest >= n - 1) {
return true;
}
}
return false;
}
};
int main() {
Solution solution;
vector<int> nums1 = {2, 3, 1, 1, 4};
vector<int> nums2 = {3, 2, 1, 0, 4};
cout << boolalpha;
cout << "Can jump (nums1): " << solution.canJump(nums1) << endl; // Output: true
cout << "Can jump (nums2): " << solution.canJump(nums2) << endl; // Output: false
return 0;
}
🧠 逐步解释
- 初始化 :
- 变量
farthest
用于记录当前能跳跃到的最远位置,初始值为0
,因为一开始我们只能从第一个位置开始。 n
是数组的大小,表示最后一个位置的索引是n-1
。
- 变量
- 遍历数组 :
- 遍历数组
nums
,对于每个位置i
,首先检查是否能到达这个位置。若i > farthest
,则返回false
,表示无法到达该位置。 - 否则,更新
farthest
,即能跳跃到的最远位置为farthest = max(farthest, i + nums[i])
。
- 遍历数组
- 判断能否到达最后一个位置 :
- 如果
farthest >= n - 1
,说明我们能够跳跃到最后一个位置,返回true
。
- 如果
- 退出循环后 :
- 如果我们遍历完数组,
farthest
依然小于最后一个位置n-1
,则返回false
,说明无法到达最后一个位置。
- 如果我们遍历完数组,
✅ 示例解释
示例 1:
输入:nums = [2, 3, 1, 1, 4]
输出:true
解释:
- 从位置 0 可以跳跃最多 2 步,可以到达位置 2。
- 从位置 1 可以跳跃最多 3 步,可以直接到达最后一个位置。
示例 2:
输入:nums = [3, 2, 1, 0, 4]
输出:false
解释:
- 从位置 0 可以跳跃最多 3 步,可以到达位置 3。
- 但是在位置 3,我们的最大跳跃长度是 0,无法再前进,因此无法到达最后一个位置。
⏱️ 复杂度分析
- 时间复杂度 :O(n),其中
n
是数组nums
的大小。我们遍历了一次数组。 - 空间复杂度:O(1),只用了常数的空间来存储变量。
🧩 小结
- 通过贪心算法,我们只需要遍历一遍数组,并利用
farthest
变量来动态更新最远可达位置,从而高效地解决了这个问题。