题目要求
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
说明:
假设你总是可以到达数组的最后一个位置。
题解
贪心
https://github.com/soulmachine/leetcode
class Solution {
public:
int jump(vector<int>& nums) {
int step=0; // 最小步数
int left=0;
int right=0; // [left,right]是当前能覆盖的区间
if(nums.size()==1) return 0;
while(left<=right){ // 尝试从每一层跳最远
++step;
const int old_right=right;
for(int i=left;i<=old_right;++i){
int new_right=i+nums[i];
if(new_right>=nums.size()-1) return step;
if(new_right>right) right=new_right;
}
left=old_right+1;
}
return 0;
}
};
执行用时 | 内存消耗 |
---|---|
8 ms | 10.2 MB |
精简代码(思路不变)
class Solution {
public:
int jump(vector<int> &nums)
{
int step = 0;
int begin = 0;
int end = 0;
while (end < nums.size()-1)
{
int temp = 0;
for (int i = begin; i <= end; i++)
{
temp = max(temp, i + nums[i]);
}
begin = end+1;
end = temp;
step++;
}
return step;
}
};
这样看起来就清晰多了,总结下思路:
- 根据begin和end确定跳跃范围。
- 每次更新end为这次所能跳到最远的位置 (end=temp)。
- 更新begin为上次的end+1。
解法2
https://github.com/soulmachine/leetcode
class Solution {
public:
int jump(vector<int>& nums) {
int step = 0;
int last = 0;
int cur = 0; // 当前所能到达的最远距离
for (int i = 0; i < nums.size(); ++i) {
if (i > last) {
last = cur;
++step;
}
cur = max(cur, i + nums[i]);
}
return step;
}
};
执行用时 | 内存消耗 |
---|---|
8 ms | 10.1 MB |
思路总结
与第一种解法不同,该解法采用的是遍历到达数组中每个元素时的情况来确定步数。
只有当超出上一步所能到达的最远距离(i>last)时 ++step 否则即是在尝试如果跳到该位置能否跳的更远。