跳格子问题(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
经验分享 程序员 微信小程序 职场和发展