我反射性想的回溯法,努力剪枝,但还是超时了。
class Solution:
def canJump(self, nums: List[int]) -> bool:
# 回溯
self.flag = False # 是否达到最后一个下标
cur = 0 # 当前下标
self.nlen = len(nums)
# print('len:',self.nlen)
def backtrack(cur):
# print('cur:', cur)
if cur == self.nlen - 1: # 到达最后一个下标
self.flag = True
return
elif cur >= self.nlen: return # 超过了
if self.flag ==True: return
if nums[cur] == 0:
# print('当前cur的step等于0:',nums[cur])
return
for step in range(nums[cur], 0 , -1):
# print('---递归前cur, step:', cur,step)
if self.flag == True:break
backtrack(cur + step)
# print('---递归后cur, step:', cur,step)
#for i in range(self.nlen):
backtrack(0)
return self.flag
看参考链接:
- 分析解题的思路1:因为只要步数不是0,都可以往前走。如果全是非0的数,那一定可以到达最后一个下标。所以思路就是如果检测到步数为0,就往回看前面有没有步数可以跳过这个0。
- 官方解析的思路2:贪心法。记录能跳的最远的下标,如果能>=最后一个下标,就算可达。max(max_step,cur_index+nums[cur_index])
class Solution:
def canJump(self, nums: List[int]) -> bool:
# 贪心
max_step = nums[0] # 从第一个下标开始,能到达的最远的下标
nlen = len(nums)
for i in range(nlen):
if i <= max_step: # 必须是要之前跳跃能到达的点
max_step = max(max_step, i + nums[i]) # 更新最远可达的下标
if max_step >= nlen - 1: # 可提前判断,不用全部遍历
return True
return False