Leetcode跳跃游戏VII

在这里插入图片描述
我的解法:
想通过遍历一遍记录位置可不可达,超时

标准解法:

class Solution:
    def canReach(self, s: str, minJump: int, maxJump: int) -> bool:

        pre = [1]+[0]*(len(s)-1)  #初始化时注意边界条件即pre[0]=1      
        for j in range(1,len(s)):
            dp= s[j]=='0' and j>=minJump and (j<=maxJump or pre[j-minJump]-pre[j-maxJump-1]>=1) #条件1和2必须同时满足,条件3和4满足其中一个
            pre[j]=pre[j-1]+dp        
        return dp

拿到这道题很容易想到一种非常直观的思路:记dp[j]表示下标j是否可达,对于每个下标j,遍历上一步可能的所有位置,即从j-maxJump遍历到j-minJump,只要这些位置中有一个可达,那么dp[j]=True。但由于minJump和maxJump可能差距很大,这样做每个状态的转移就需要O(n)时间,的总时间复杂度能达到O(n^2),以本题的数据范围肯定不允许。注意到寻找j-maxJump到j-minJump之间有没有有效位置,本质上是个区间和问题,即要求sum(dp[j-maxJump:j-minJump+1])>0,而区间和可以通过前缀和来O(1)解决,因此可以用一个数组记录dp数组的前缀和,就不需要O(n)转移了。

由于题目保证起点一定不是障碍,因此dp[0]=True,pre[0]=1。遍历下标j时,dp[j]=True需要满足下列条件:
1.s[j]==‘0’。如果不满足,说明下标j本身就是个障碍,不可达。
2.j>=minJump。只跳1步也至少到minJump的位置,0到minJump之间的所有位置都不可达。
3.j<=maxJump。当满足条件1和2时,如果满足此条件,第一步就可以跳到下标j。
4.j>maxJump,同时sum(dp[j-maxJump:j-minJump+1])>0。这时虽然一步跳不到j,但j-maxJump到j-minJump之间存在可达的位置,因此j也可达。
其中条件1和2必须同时满足,条件3和4需要满足其中一个,条件4可以通过前缀和来判断。

这样实现起来就不会在细节上出错了。最后返回dp[-1]就是答案。事实上我们不需要dp数组,只需要前缀和数组,因为dp[j]并不由dp数组里的元素转移而来。

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
链接:https://leetcode.cn/problems/jump-game-vii/solution/qian-zhui-he-you-hua-dpp-by-v5qyy4q65w-5xml/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值