传送门:45. 跳跃游戏 II 题目描述: 给你一个非负整数数组 nums ,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。假设你总是可以到达数组的最后一个位置。
样例:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
输入: nums = [2,3,0,1,4]
输出: 2
数据范围: 1 <= nums.length <= 10^4 0 <= nums[i] <= 1000
思路1:贪心的倒着跳,从最后位置往前,找到能跳到最后位置的最小下标(有多个可以跳到最后位置,找下标最小的那个,这样代价最小),然后找跳到倒数第二步的,一直往前找,知道position找到第一个位置。时间复杂度为O(n^2).
代码:
class Solution {
public int jump(int[] nums) {
int ans=0;
int position=nums.length-1;
while(position>0){
for(int i=0;i<position;i++){
if(i+nums[i]>=position){
ans++;
position=i;
break;
}
}
}
return ans;
}
}
思路2:从前往后跳,每次选择当前能跳到最远的位置,作为边界,到达边界时,更新边界并将跳跃次数增加 1,因为中间不管是大于边界还是等于边界,都会跳一次。
需要注意的是,不需要访问最后一个元素,这是因为在访问最后一个元素之前,边界一定大于等于最后一个位置,否则就无法跳到最后一个位置了。如果访问最后一个元素,在边界正好为最后一个位置时候,会多算一次。时间复杂度为O(n).
class Solution {
public int jump(int[] nums) {
int ans=0;
int end=0;
int maxNum=0;
for(int i=0;i<nums.length-1;i++){
maxNum=Math.max(maxNum,i+nums[i]);
if(i==end){
end=maxNum;
ans++;
}
}
return ans;
}
}
|