45. 跳跃游戏 II
mengjian-github opened this issue · comments
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
一个直观的想法是利用回溯算法暴力求解:
/**
* @param {number[]} nums
* @return {number}
*/
var jump = function(nums) {
let result = Infinity;
function backtrack(sum = 0, index = 0) {
if (index >= nums.length - 1) {
// 找到一个
if (index === nums.length - 1) {
result = Math.min(result, sum);
}
return;
}
let j = nums[index];
while (j > 0) {
// 跳j步
if(index + j <= nums.length) {
sum++;
backtrack(sum, index + j);
// 回溯
sum--;
}
j--;
}
}
backtrack();
return result;
};
但是暴力算法无法通过LeetCode
此题可使用贪心算法完成:
每次跳动的距离,选择跳动后再跳一次最远的那一个
/**
* @param {number[]} nums
* @return {number}
*/
var jump = function(nums) {
let result = 0;
let i = 0;
while(i < nums.length - 1) {
let jump = nums[i];
let choose = jump;
while (jump > 0) {
if (i + jump >= nums.length - 1) {
// 可以直接跳出去
choose = jump;
break;
}
// 选择jump到达的地方
const jumpTarget = nums[i+jump] + i+jump;
const chooseTarget = nums[i+choose] + i+choose;
if (jumpTarget > chooseTarget) {
choose = jump;
}
jump--;
}
// 做出新选择
result++;
i += choose;
}
return result;
};