思路
思路转换: 通过题目中的跳跃规则,最多能跳多远?如果能够越过最后一格,返回 true,否则返回 false
贪心:每一步都跳到最远处,来与全局最优解farest比较,通过每一步的最优解,更新全局最优解。
代码
/**
* @param {number[]} nums
* @return {boolean}
*/
var canJump = function(nums) {
let n = nums.length;
if(n==1) return true;
let farest = 0;
for(let i=0; i<n-1; i++){
farest = Math.max(farest, i+nums[i]);
if(farest<=i) return false; // !important: 到不了i位置, 肯定到不了终点。
}
return farest>=n-1;
};
思路
动态规划 dp[i]: 从下标i跳到最后一个位置最少的次数。
dp[i] = 1 + min(dp[i+1,..., i+nums[i]]), 其中i+nums[i]就是i位置能跳到的最远位置。
代码
/**
* @param {number[]} nums
* @return {number}
*/
var jump = function(nums) {
// dp[i]: 从下标i跳到最后一个位置最少的次数。
let n = nums.length;
if(n==1) return 0;
let dp = new Array(n).fill(0);
for(let i=n-2; i>=0; i--){
dp[i] = 1 + Math.min(...dp.slice(i+1, i+nums[i]+1));
}
return dp[0];
};
tips
第二题也有贪心思路
比如上图这种情况应该跳多少呢?
显然应该跳 2 步跳到索引 2,因为nums[2]的可跳跃区域涵盖了索引区间[3…6],比其他的都大。如果想求最少的跳跃次数,那么往索引 2 跳必然是最优的选择。
你看,这就是贪心选择性质,我们不需要「递归地」计算出所有选择的具体结果然后比较求最值,而只需要做出那个最有「潜力」,看起来最优的选择即可。