目录
三种思路
1.动态规划(结果超时)
时间复杂度为o(n^2)
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
'''最后一步A(n-1)是由前一步Ai跳过来的
则只要满足:
1.能跳到前一步Ai
2.n-1-i<=nums[i](前一步到最后一步的距离<=最大跳的距离num[i])
第二个条件很好判断,则关键就变为能否跳到第i个石头
'''
n=len(nums)
dp=[0]*n #dp[i]表示青蛙能否跳到第i块石头
dp[0]=1
for i in range(1,n):
for j in range(i):
if dp[j] and i-j<=nums[j]:
dp[i]=1
break
return (True if dp[n-1] else False)
2.贪心法
时间复杂度为o(nlog(n))
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
'''贪心法
每一次都跳到选择最多(即跳的最远)的位置,这样他下一步能走的就包括了所有解,如果都不能到,就说明没有解(因此这一题能用贪心法)
即max(nums[i]+i-pos)
'''
n=len(nums)-1
pos=0 #记录当前的位置
if n==0:
return True
if nums[0]==0:
return False
for i in range(1,n+1):
if pos+nums[pos]>=n:
return True
else:
pos+=max(map(lambda x:(nums[pos+x]+x,x),range(1,nums[pos]+1)))[1]#跳到选择最多的位置
if pos>=n:
return True
if nums[pos]==0: #动不了了
return False
else:
return False
3.换一种思路
受LeetCode讨论区ylem大佬启发,将格子上的数字作为能量,而每走一步就需要耗费一个能量,如果在能量耗尽之前到了终点,那么就成功,否则失败(期间可以拿自己身上的能量与格子的能量进行交换),这样时间复杂度就为o(n)
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
n=len(nums)
if n==1:
return True
energy=nums[0]
for i in range(1,n):
if energy==0: #每次启动之前都要检查一下是否有能量
return False
energy-=1
if energy<nums[i]:
energy=nums[i]
else:
return True