Leetcode 3661. Maximum Walls Destroyed by Robots

1. 解题思路

这一题思路上就是一个动态规划+分类讨论的思路。

我们首先将所有的机器人以及墙壁位置顺序排列,然后从左往右依次考察每一个机器人向左以及向右射出子弹时其所能到达的范围,然后通过二分查找的方式去查找对应范围内的墙壁个数即可。

因此,我们只需要设计一个迭代函数dp(idx, dir),前者表示当前考察的机器人,后者表示前一个机器人的子弹射出方向,由此我们即可在 O ( 2 N ) O(2N) O(2N)的复杂度内将结果计算完毕。

但是需要注意的是,在实际计算子弹射出范围的时候,我们需要考察每一种情况下的子弹范围交叠情况,然后需要扣除掉多余的部分,这个还是需要分类讨论好好细化一下的,这里就不过多赘述了,有兴趣的读者对着代码自己想一下就行了。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maxWalls(self, robots: List[int], distance: List[int], walls: List[int]) -> int:
        robs = sorted([(i, d) for i, d in zip(robots, distance)])
        walls = sorted(walls)
        
        n, m = len(robs), len(walls)

        @lru_cache(None)
        def dp(idx, ori):
            if idx >= n:
                return 0
            loc, dis = robs[idx]
            rbound = min(loc + dis, robs[idx+1][0]) if idx < n-1 else loc + dis
            rcount = bisect_left(walls, rbound+1) - bisect_left(walls, loc)
            lbound = max(loc - dis, robs[idx-1][0]) if idx > 0 else loc - dis
            lcount = bisect_left(walls, loc+1) - bisect_left(walls, lbound)
            if ori == "right":
                if robs[idx-1][0] + robs[idx-1][1] >= loc:
                    wid = bisect.bisect_left(walls, loc)
                    if wid < m and walls[wid] == loc:
                        return rcount + dp(idx+1, "right") - 1
                    else:
                        return rcount + dp(idx+1, "right")
                elif robs[idx-1][0] + robs[idx-1][1] >= lbound:
                    _lbound = min(robs[idx-1][0] + robs[idx-1][1]+1, loc+1)
                    _lcount = bisect_left(walls, loc+1) - bisect_left(walls, _lbound)
                    return max(rcount + dp(idx+1, "right"), _lcount + dp(idx+1, "left"))
                else:
                    return max(rcount + dp(idx+1, "right"), lcount + dp(idx+1, "left"))
            else:
                if ori == "left" and lbound == robs[idx-1][0]:
                    wid = bisect.bisect_left(walls, lbound)
                    if wid < m and walls[wid] == lbound:
                        return max(rcount + dp(idx+1, "right"), lcount + dp(idx+1, "left")-1)
                return max(rcount + dp(idx+1, "right"), lcount + dp(idx+1, "left"))
        
        return dp(0, "")

提交代码评测得到:耗时1933ms,占用内存304.63MB。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值