问题背景
给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false。
示例 1: 输入:nums = [2,3,1,1,4] 输出:true 解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2: 输入:nums = [3,2,1,0,4] 输出:false 解释:无论怎样,总会到达下标为 3
的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。
跳跃游戏是一道典型的贪心算法问题。题目要求判断是否能从数组的第一个下标跳跃到最后一个下标。我们可以利用贪心算法的思想,通过维护能够到达的最远位置来解决这个问题。
解题思路
我们可以使用贪心算法来解决这个问题,具体步骤如下:
- 初始化一个变量
maxReach
,表示当前能够到达的最远位置,初始值为 0。 - 遍历数组中的每一个元素
nums[i]
:- 如果当前下标
i
超过了maxReach
,说明我们无法到达当前位置,返回false
。 - 更新
maxReach
为max(maxReach, i + nums[i])
。 - 如果
maxReach
已经大于或等于数组的最后一个下标,返回true
。
- 如果当前下标
- 如果遍历完数组后
maxReach
仍然小于最后一个下标,返回false
。
示例讲解
示例 1
输入:nums = [2,3,1,1,4]
- 初始化
maxReach = 0
- 遍历数组:
i = 0
,nums[0] = 2
,更新maxReach = max(0, 0 + 2) = 2
i = 1
,nums[1] = 3
,更新maxReach = max(2, 1 + 3) = 4
- 由于
maxReach
已经大于等于最后一个下标,返回true
示例 2
输入:nums = [3,2,1,0,4]
- 初始化
maxReach = 0
- 遍历数组:
i = 0
,nums[0] = 3
,更新maxReach = max(0, 0 + 3) = 3
i = 1
,nums[1] = 2
,更新maxReach = max(3, 1 + 2) = 3
i = 2
,nums[2] = 1
,更新maxReach = max(3, 2 + 1) = 3
i = 3
,nums[3] = 0
,不更新maxReach
i = 4
时发现i > maxReach
,返回false
代码实现
Python 的代码实现:
class Solution:
def canJump(self, nums: List[int]) -> bool:
maxReach = 0
for i in range(len(nums)):
if i > maxReach:
return False
maxReach = max(maxReach, i + nums[i])
if maxReach >= len(nums) - 1:
return True
return False
Java的代码实现:
class Solution {
public boolean canJump(int[] nums) {
int maxReach = 0;
for (int i = 0; i < nums.length; i++) {
if (i > maxReach) {
return false;
}
maxReach = Math.max(maxReach, i + nums[i]);
if (maxReach >= nums.length - 1) {
return true;
}
}
return false;
}
}
总结
通过维护能够到达的最远位置maxReach
,可以高效地判断是否能够从数组的第一个下标跳跃到最后一个下标。算法的时间复杂度为 O(n)
,n
是数组的长度。