100道面试必会算法-34-跳跃游戏 | && 跳跃游戏||
给定一个长度为 n
的 0 索引 整数数组 nums
。初始位置为 nums[0]
。
每个元素 nums[i]
表示从索引 i
向前跳转的最大长度。换句话说,如果你在 nums[i]
处,你可以跳转到任意 nums[i + j]
处:
0 <= j <= nums[i]
i + j < n
返回到达 nums[n - 1]
的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]
。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
给你一个非负整数数组 nums
,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true
;否则,返回 false
。
问题描述
跳跃游戏是一个经典的算法问题,给定一个非负整数数组 nums
,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。目标是使用最少的跳跃次数到达数组的最后一个位置。
算法思路
给定数组 nums
,从起始位置开始,以贪心的策略选择每一步能够跳跃的最远距离,直到到达数组的末尾。具体步骤如下:
- 初始化起始位置
start
为 0,结束位置end
为 1,跳跃次数count
为 0。 - 在循环中,不断更新当前能够跳跃到的最远位置
maxpos
。 - 遍历从
start
到end
之间的元素,找到能够跳跃到的最远位置。 - 更新起始位置
start
为当前结束位置end
,更新结束位置end
为下一次能够跳跃到的最远位置maxpos + 1
。 - 每次循环增加跳跃次数
count
。 - 循环直到结束位置
end
超过数组长度。
算法分析
- 时间复杂度:O(n),其中 n 为数组的长度,因为在每个位置只需要遍历一次。
- 空间复杂度:O(1),只需要常数级别的额外空间。
代码实现
java
class Solution {
// 定义一个方法,计算跳跃次数
public int jump(int[] nums) {
int start = 0; // 起始位置
int end = 1; // 结束位置
int count = 0; // 跳跃次数
// 循环直到达到最后一个位置
while (end < nums.length) {
int maxpos = 0; // 最大跳跃位置
// 遍历当前范围内的数字,找到能跳到的最远位置
for (int i = start; i < end; i++) {
maxpos = Math.max(maxpos, i + nums[i]);
}
start = end; // 更新起始位置为当前结束位置
end = maxpos + 1; // 更新结束位置为下一次能跳到的最远位置
count++; // 增加跳跃次数
}
return count; // 返回跳跃次数
}
}
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。
解题思路:
-
如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点
-
可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离 不断更新
-
如果可以一直跳到最后,就成功了
k是道路,i是人的位置,只要道路不断延伸,就能走到终点
java
class Solution {
public boolean canJump(int[] nums) {
int k=0; // 当前能够到达的最远位置
for(int i=0;i<nums.length;i++){
if(k<i) return false; // 如果当前位置超过了能够到达的最远距离,则无法到达终点
k=Math.max(k,i+nums[i]); // 更新能够到达的最远位置
}
return true; // 循环结束后仍未返回false,则可以到达终点
}
}