跳格子问题(LeetCode第55题 跳跃游戏)平民解
三种思路
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