leetcode
解题思路(基于贪心算法)
判断能否到达最后一个下标的核心在于 动态维护当前能覆盖的最远跳跃距离。通过遍历数组,实时更新可覆盖的最远位置,若该位置能覆盖终点则返回 true
,若遍历过程中发现当前位置超出最远覆盖范围则返回 false。
关键步骤:
- 初始化变量:
maxReach
表示当前能到达的最远位置,初始为0(起点)。 - 遍历数组:对于每个位置
i
:- 若
i > maxReach
,说明无法到达当前位置,直接返回false。
- 更新
maxReach
为max(maxReach, i + nums[i])
(即从当前位置能跳跃的最远距离)。 - 若
maxReach >= len(nums)-1
,说明已覆盖终点,返回true。
- 若
- 边界处理:若数组长度为1,直接返回
true。
Golang 实现代码
func canJump(nums []int) bool {n := len(nums)if n == 0 {return false // 空数组直接返回false(题目未明确此情况,根据示例推断) }if n == 1 {return true // 单元素数组无需跳跃 }maxReach := 0 // 当前能到达的最远位置for i := 0; i < n; i++ {if i > maxReach { // 当前位置不可达return false}maxReach = max(maxReach, i + nums[i]) // 更新最远覆盖范围if maxReach >= n-1 { // 已覆盖终点return true}}return false }func max(a, b int) int {if a > b {return a}return b }
代码解析
-
初始条件处理:
- 单元素数组直接返回
true
,因起点即终点。 -
动态维护
maxReach
:- 遍历时若发现当前位置
i
超过maxReach
,说明无法继续跳跃,返回false
(例如示例2中到达位置3时,maxReach
为3,但i=4
时超出范围)。 - 更新
maxReach
时,取当前值和新计算值i + nums[i]
的较大值(如示例1中,位置1的i + nums[i] = 4
,直接覆盖终点)。
- 遍历时若发现当前位置
-
提前终止优化:
- 一旦
maxReach
覆盖终点,立即返回true
,避免冗余遍历。
- 一旦
复杂度分析
维度 | 说明 |
---|---|
时间复杂度 | O(n),只需一次遍历数组。 |
空间复杂度 | O(1),仅需常数级变量存储状态。 |
示例验证
-
示例1:
nums = [2,3,1,1,4]
i=0
时,maxReach = 0 + 2 = 2
,未覆盖终点。i=1
时,maxReach = max(2, 1 + 3) = 4
,覆盖终点,返回true。
-
示例2:
nums = [3,2,1,0,4]
i=3
时,maxReach = 3
,但后续i=4
超出maxReach
,返回false。
扩展思考
- 动态规划解法(时间复杂度 O(n²)):
定义dp[i]
表示能否到达位置i
,但贪心算法更高效。 - 跳跃游戏 II(求最少跳跃次数):
可在贪心基础上结合双指针优化。
通过上述方法,可高效判断跳跃可行性,适用于大规模数组。