Before attempting this problem, you should be comfortable with:
When a bomb detonates, it triggers other bombs within its blast radius. This creates a chain reaction that can be modeled as a directed graph. Bomb A has an edge to bomb B if B is within A's blast radius. Note that this relationship is not symmetric since bombs have different radii. To find the maximum detonation, we try detonating each bomb and use DFS to count how many bombs explode in the chain reaction.
dfs to count all reachable bombs.dfs, use a visited set to track which bombs have already detonated and recursively visit all bombs that can be triggered.class Solution:
def maximumDetonation(self, bombs: list[list[int]]) -> int:
adj = [[] for _ in range(len(bombs))]
for i in range(len(bombs)):
x1, y1, r1 = bombs[i]
for j in range(i + 1, len(bombs)):
x2, y2, r2 = bombs[j]
d = (x1 - x2) ** 2 + (y1 - y2) ** 2
if d <= r1 ** 2:
adj[i].append(j)
if d <= r2 ** 2:
adj[j].append(i)
def dfs(i, visit):
if i in visit:
return 0
visit.add(i)
for nei in adj[i]:
dfs(nei, visit)
return len(visit)
res = 0
for i in range(len(bombs)):
res = max(res, dfs(i, set()))
return resThe chain reaction of bomb detonations can also be explored level by level using BFS. Starting from an initial bomb, we explore all bombs it directly triggers, then all bombs those trigger, and so on. This approach naturally models the wave-like spread of explosions.
dfs approach, where an edge from A to B means bomb A can trigger bomb B.visit array.class Solution:
def maximumDetonation(self, bombs: list[list[int]]) -> int:
n = len(bombs)
adj = [[] for _ in range(n)]
for i in range(n):
x1, y1, r1 = bombs[i]
for j in range(i + 1, n):
x2, y2, r2 = bombs[j]
d = (x1 - x2) ** 2 + (y1 - y2) ** 2
if d <= r1 ** 2:
adj[i].append(j)
if d <= r2 ** 2:
adj[j].append(i)
res = 0
for i in range(n):
q = deque([i])
visit = [False] * n
visit[i] = True
count = 1
while q:
node = q.popleft()
for nei in adj[node]:
if not visit[nei]:
visit[nei] = True
count += 1
q.append(nei)
res = max(res, count)
return resThis is the same approach as recursive DFS but uses an explicit stack instead of the call stack. This avoids potential stack overflow issues for very large inputs and can be more efficient in some languages due to reduced function call overhead.
visit array.class Solution:
def maximumDetonation(self, bombs: list[list[int]]) -> int:
n = len(bombs)
adj = [[] for _ in range(n)]
for i in range(n):
x1, y1, r1 = bombs[i]
for j in range(i + 1, n):
x2, y2, r2 = bombs[j]
d = (x1 - x2) ** 2 + (y1 - y2) ** 2
if d <= r1 ** 2:
adj[i].append(j)
if d <= r2 ** 2:
adj[j].append(i)
res = 0
for i in range(n):
stack = [i]
visit = [False] * n
visit[i] = True
count = 1
while stack:
node = stack.pop()
for nei in adj[node]:
if not visit[nei]:
visit[nei] = True
count += 1
stack.append(nei)
res = max(res, count)
return resA common mistake is assuming that if bomb A can trigger bomb B, then B can also trigger A. This is incorrect because bombs have different radii. The graph is directed: an edge from A to B exists only if B is within A's blast radius.
# Wrong: Adding bidirectional edges unconditionally
if d <= r1 ** 2:
adj[i].append(j)
adj[j].append(i) # Incorrect!
# Correct: Check each direction separately
if d <= r1 ** 2:
adj[i].append(j)
if d <= r2 ** 2:
adj[j].append(i)When calculating the squared distance between bombs, the intermediate values can overflow 32-bit integers. Coordinates can be up to 10^5 and squaring the difference can exceed INT_MAX. Always use 64-bit integers for distance calculations.
// Wrong: Overflow possible
int d = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
// Correct: Cast to long before multiplication
long d = (long)(x1 - x2) * (x1 - x2) + (long)(y1 - y2) * (y1 - y2);Computing the actual Euclidean distance using sqrt() introduces floating-point precision errors. Instead, compare squared distances directly to avoid precision issues.
# Wrong: Floating-point precision issues
import math
if math.sqrt((x1-x2)**2 + (y1-y2)**2) <= r1:
adj[i].append(j)
# Correct: Compare squared values
if (x1-x2)**2 + (y1-y2)**2 <= r1**2:
adj[i].append(j)