描述
该题来自于力扣第45题
分析
仔细想想,如果从当前位置\(i\)最远可以第\(i+k\)个位置,那么从当前位置跳到\(i+1\)到\(i+k\)位置的步数是一样的,比如nums=[2,3,1,1,4]
,那么从\(i=0\)开始跳,最远可以跳跃到\(i+nums[i]=2\)个位置,即要到达3 1
只需一步,那么写算法的时候,可以一次更新每个位置要达到的最小步数,但是显然可以继续优化;
有必要每次往后更新每个位置的步数吗?因为从位置0
最远能跳到位置2
,所以位置1,2
都是1
步到达,只有当超过位置2
位置时,步数才去更新(+1),这样就好了;
此时考虑另一个问题,到达位置1,2
的最小步数确定了,那后面的位置怎么确定呢?显然是位置1,2
之中能跳到的最远距离了,所以遍历时,还需要计算j+nums[j]
的最大值,即跳2
步能达到的最大距离,其中j
是跳1
步能达到的最远距离。
算法
- 首先令
step
为到达当前位置所需的步数,显然到达初始位置只需0
步,从而设置初始step=0
;令currReach
为当前能达到的最远位置,显然设置初始currReach=0
;令nextReach
为下一个能达到的最远位置,同样初始nextReach=0
; - 遍历数组
i in [0, n-1]
- 判断当前位置
i
是否超过了currReach
,如果是,则执行第4步,否则执行第5步; - 超过了,那么
step=step+1
,且currReach = nextReach
,即当前能到达的最远距离更新为下一次能到达的最远距离; - 没超过,继续找下一次能到达的最远距离,即更新
nextReach = max(nextReach, i+nums[i])
; - 遍历结束,返回
step
代码
c++
1 | class Solution { |