1. 解题思路
这一题的话我的思路就是通过一个DSU算法找到所有有交叠的圆的集合,然后看他们一起构成的矩形覆盖区域是否会阻断目标路线。
而矩形区域阻断目标路线的判断方法的话,我们可以通过以下几个条件进行判断:
- 矩形区域是否覆盖了左右边界,即横向阻断了所有可能路线;
- 矩形区域是否覆盖了上下边界,即纵向阻断了所有可能路线;
- 矩形区域是否直接覆盖了起点或者终点。
而关于DSU算法,我们之前已经有过一篇博客(经典算法:并查集(DSU)结构简介)对其进行过介绍了,因此这里就不过多进行展开了。
2. 代码实现
给出python代码实现如下:
class DSU:
def __init__(self, N):
self.root = [i for i in range(N)]
def find(self, k):
if self.root[k] != k:
self.root[k] = self.find(self.root[k])
return self.root[k]
def union(self, a, b):
x = self.find(a)
y = self.find(b)
if x != y:
self.root[y] = x
return
class Solution:
def canReachCorner(self, X: int, Y: int, circles: List[List[int]]) -> bool:
n = len(circles)
dsu = DSU(n)
for i in range(n-1):
x1, y1, r1 = circles[i]
for j in range(i+1, n):
x2, y2, r2 = circles[j]
if math.sqrt((x1-x2)**2 + (y1-y2)**2) <= r1+r2:
dsu.union(i, j)
def is_blocked(lbound, rbound, dbound, ubound):
if lbound <= 0 and rbound >= X:
return True
elif dbound <= 0 and ubound >= Y:
return True
elif lbound <= X <= rbound and dbound <= Y <= ubound:
return True
elif lbound <= 0 <= rbound and dbound <= 0 <= ubound:
return True
return False
boundary = {}
for i in range(n):
x, y, r = circles[i]
c = dsu.find(i)
if c not in boundary:
boundary[c] = [x-r, x+r, y-r, y+r]
else:
boundary[c][0] = min(boundary[c][0], x-r)
boundary[c][1] = max(boundary[c][1], x+r)
boundary[c][2] = min(boundary[c][2], y-r)
boundary[c][3] = max(boundary[c][3], y+r)
if is_blocked(*boundary[c]):
return False
return True
提交代码评测得到:耗时3644ms,占用内存17.4MB。