题目链接
题目描述
给你一个非负整数数组 nums
,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2
。
从下标为 0 跳到下标为 1 的位置,跳 1
步,然后跳 3
步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
提示:
1 <= nums.length <= 104
-
解题思路
方法一:动态规划
dp[i] 代表跳到下标 i 处需要的最小跳跃数
状态转移方程为:
dp[j] = dp[j] == 0 ? dp[i] + 1 : Math.min(dp[j],dp[i] + 1);class Solution {
public int jump(int[] nums) {
int[] dp = new int[nums.length];
// dp[i] 代表跳到下标 i 处需要的最小跳跃数
// dp[0] = 0
for(int i = 0; i < nums.length; ++i){
for(int j = i + 1; j < nums.length && j <= i + nums[i]; ++j){
// 如果当前位置未被跳到过,则当前位置需要至少 dp[i] + 1 次,表示从 i 位置跳过来
// 如果当前位置被跳到过,则当前位置需要至少 Math.min(dp[j],dp[i] + 1) 次, 表示选择之前跳跃数和当前 i 处跳跃数之间的最小值
dp[j] = dp[j] == 0 ? dp[i] + 1 : Math.min(dp[j],dp[i] + 1);
}
}
return dp[nums.length-1];
}
}
时间复杂度 O(n)
-
方法二:贪心
查找最远范围maxRight,
上一次跳的最远位置为end
res为步数class Solution { public int jump(int[] nums) { int len = nums.length; int maxRight = -1; int end = 0; int res = 0; for(int i = 0; i < len - 1; ++i){ // 获取当前可以到达的最远位置 maxRight = Math.max(maxRight, i + nums[i]); // end表示上一次跳跃的最远位置 // 当上一次跳跃的位置为当前位置时,可以由当前位置跳到 maxRight if(end == i){ end = maxRight; ++res; } } return res; } }
时间复杂度 O(n)
- 空间复杂度 O(1)