Leetcode每日一题 20240722 2101.引爆最多的炸弹

题目描述

给你一个炸弹列表。一个炸弹的 爆炸范围 定义为以炸弹为圆心的一个圆。
炸弹用一个下标从 0 开始的二维整数数组 bombs 表示,其中 bombs[i] = [xi, yi, ri] 。xi 和 yi 表示第 i 个炸弹的 X 和 Y 坐标,ri 表示爆炸范围的 半径 。
你需要选择引爆 一个 炸弹。当这个炸弹被引爆时,所有 在它爆炸范围内的炸弹都会被引爆,这些炸弹会进一步将它们爆炸范围内的其他炸弹引爆。
给你数组 bombs ,请你返回在引爆 一个 炸弹的前提下,最多 能引爆的炸弹数目。
2101.引爆最多的炸弹

测试案例及提示

示例1:
Alt
输入:bombs = [[2,1,3],[6,1,4]]
输出:2
解释:
上图展示了 2 个炸弹的位置和爆炸范围。
如果我们引爆左边的炸弹,右边的炸弹不会被影响。
但如果我们引爆右边的炸弹,两个炸弹都会爆炸。
所以最多能引爆的炸弹数目是 max(1, 2) = 2 。

示例 2:
Alt
输入:bombs = [[1,1,5],[10,10,5]]
输出:1
解释:
引爆任意一个炸弹都不会引爆另一个炸弹。所以最多能引爆的炸弹数目为 1 。

示例 3:
Alt输入:bombs = [[1,2,3],[2,3,1],[3,4,2],[4,5,3],[5,6,4]]
输出:5
解释:
最佳引爆炸弹为炸弹 0 ,因为:
炸弹 0 引爆炸弹 1 和 2 。红色圆表示炸弹 0 的爆炸范围。
炸弹 2 引爆炸弹 3 。蓝色圆表示炸弹 2 的爆炸范围。
炸弹 3 引爆炸弹 4 。绿色圆表示炸弹 3 的爆炸范围。
所以总共有 5 个炸弹被引爆。

提示:
1 <= bombs.length <= 100
bombs[i].length == 3
1 <= xi, yi, ri <= 105

解题思路

转换问题,将每个炸弹看作图中的节点,而是否能通过一个炸弹引爆另一个炸弹看作是有向边。(不是无向边的原因是,炸弹a的爆炸范围波及炸弹b时,炸弹b的爆炸范围可能不能波及炸弹a。具体可看示例1中的两个炸弹)
因此可以先建立一个图,记录每个炸弹的爆炸波及情况。然后对于每个节点,使用DFS(深度优先遍历),就可找到引爆一颗炸弹可以波及的炸弹数了。
DFS入门可以看DFS图论
python

class Solution:
    def maximumDetonation(self, bombs: List[List[int]]) -> int:
        def canBoom(bomb1: List[int], bomb2: List[int]) -> List[int]:
            ret = False
            distancePow = pow((bomb1[0] - bomb2[0]), 2) + pow((bomb1[1] - bomb2[1]), 2)
            if distancePow <= bomb1[-1] ** 2:
                ret = True
            return ret

        n = len(bombs)
        edges = defaultdict(list)
        for i in range(n):
            for j in range(n):
                if i != j and canBoom(bombs[i], bombs[j]):
                    edges[i].append(j)
        
        def dfs(node: int, visited: List[bool]) -> int:
            visited[node] = True
            count = 1
            for neighbor in edges[node]:
                if not visited[neighbor]:
                    count += dfs(neighbor, visited) 
            return count

        ans = 0   
        for i in range(n):
            visited = [False] * n
            cnt = dfs(i, visited)
            ans = max(ans, cnt)
        return ans
  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值