1 题目
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
Example:
Input: [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2.
Jump 1 step from index 0 to 1, then 3 steps to the last index.
2 尝试解
2.1 分析
给定一个非负数数组nums,从位置0开始向最后的位置跳跃。在位置i上能跳跃的最大步数为nums[i]。假设给定的数组一定可以调到最后位置,问跳到最后位置所需最小步数。
用数组least表示从位置i到最后位置所需的最小步数,除least.back()=0表示最后位置不需要跳跃即可到达目标时,其余位置初始化为-1。然后从倒数第二位向前遍历。每次遍历找当前位置i所能到达的所有位置i+j,j in [1,nums[i]],然后去最小值即可。
但是这个方法复杂度为O(N^2),最后一个测试用例过不去,该测试用例为[25000,24999,24998,....,1,0]。考虑nums[i]>nums[i+1],即从位置i可以到达位置i+1所有可达位置,如果存在一个最优解路径,其中经过位置i,那么完全可以用位置i+1替换掉,所以位置i+1完全可以忽略。所以上述遍历时,可以加一个条件,nums[i-1]>nums[i]→continue。
2.2 代码
class Solution {
public:
int jump(vector<int>& nums) {
vector<int> least(nums.size(),-1);
least.back() = 0;
for(int i = nums.size()-2; i >= 0; i--){
if(i > 0 && nums[i]<nums[i-1]) continue;
for(int j = 1; j <= nums[i] && i+j < nums.size(); j++){
if(least[i+j] >= 0){
least[i] = min(1+least[i+j],(least[i]==-1?INT_MAX:least[i]));
}
}
}
return least[0];
}
};
3 标准解
3.1 分析
可以将该问题转化为BFS问题。求出第1步可以到达的范围[start,end],然后再求从该范围中任意位置出发,可以到达的最远范围[end+1,end'],并且步数变为2,直到达到终点。
3.2 代码
class Solution {
public:
int jump(vector<int>& nums) {
int n = nums.size(), step = 0, start = 0, end = 0;
while (end < n - 1) {
step++;
int maxend = end + 1;
for (int i = start; i <= end; i++) {
if (i + nums[i] >= n - 1) return step;
maxend = max(maxend, i + nums[i]);
}
start = end + 1;
end = maxend;
}
return step;
}
};