难度: Hard
Submission
运行时间: 288 ms
内存: 36.2 MB
""" iteration + sorting + binary search T: O(n+Cm) S: O(1) if circle j can hoop the toyi, then toyi is Inclusion, inscribed or totally overlapping with cicle j xj.e., 0 <= d <= r - ri since 1 <= r, ri <= 10 then d <= 10-1=9 since d is integer, then d is in range [0, 9] we can iterates all possble centers of circle for each toy """ class Solution: def circleGame(self, toys: List[List[int]], circles: List[List[int]], r: int) -> int: def check(xi: int, yi: int, ri: int) -> bool: """ whether ith toy can be hooped by any circle """ d = r-ri if d < 0: return False left, right = xi-d, xi+d down, up = yi-d, yi+d for xj in range(left, right+1): if not yjs[xj]: continue a = bisect_left(yjs[xj], down) b = bisect_right(yjs[xj], up) for idx in range(a, b): yj = yjs[xj][idx] if (xj-xi)**2 + (yj-yi)**2 <= d**2: return True return False m, n = len(toys), len(circles) # 1. O(nlogn) sort circles array by xj and yj circles.sort() # 2. O(n) store yjs of each xj in circles array yjs = defaultdict(list) for xj, yj in circles: yjs[xj].append(yj) # 3. O(m) iterates over toys array ans = sum(check(*toy) for toy in toys) return ans
Explain
此题解采用迭代+排序+二分搜索的方法来确定玩具是否被套圈。首先,对所有的圈按照x坐标进行排序,并为每个x坐标建立一个列表,存储对应的y坐标。对于每个玩具,根据其位置和大小计算出可能套中该玩具的圈的潜在x和y坐标范围。接着,对每个玩具遍历这个范围内的所有潜在圈的坐标,使用二分搜索确定潜在的y坐标。若计算得出的圈心到玩具心的距离小于或等于圈半径减去玩具半径的平方,则该玩具被套中。
时间复杂度: O(n + Cm)
空间复杂度: O(n)
class Solution: def circleGame(self, toys: List[List[int]], circles: List[List[int]], r: int) -> int: def check(xi: int, yi: int, ri: int) -> bool: # 检查是否可以将第i个玩具套圈 d = r-ri if d < 0: return False left, right = xi-d, xi+d down, up = yi-d, yi+d for xj in range(left, right+1): if not yjs[xj]: continue a = bisect_left(yjs[xj], down) b = bisect_right(yjs[xj], up) for idx in range(a, b): yj = yjs[xj][idx] if (xj-xi)**2 + (yj-yi)**2 <= d**2: return True return False m, n = len(toys), len(circles) circles.sort() # 按x坐标排序圈的数组 yjs = defaultdict(list) # 为每个x坐标存储y坐标的列表 for xj, yj in circles: yjs[xj].append(yj) ans = sum(check(*toy) for toy in toys) # 对所有玩具应用check函数并计数 return ans
Explore
在题解中选择对圈的x坐标进行排序是因为这样可以根据玩具的x坐标快速地定位可能与玩具相交的圈的潜在范围。通过排序x坐标,我们可以利用二分搜索快速缩小圈的搜索范围,从而减少不必要的检查。如果同时对x和y坐标排序,则会增加处理排序后数据的复杂性,因为我们需要同时考虑二维上的位置关系,这可能导致效率降低。因此,单独对x坐标进行排序并结合y坐标的列表,是一个在效率和实现复杂度之间较好的折中。
在排序圈的x坐标后,使用字典来存储每个x坐标对应的y坐标列表是为了快速访问和检索特定x坐标下所有可能的y坐标。这种数据结构的优势在于它提供了快速的查找时间和灵活的数据访问。对于每个特定的x坐标,我们可以直接通过字典访问所有相关的y坐标,而不需要遍历整个圈的列表。这样可以显著提高查询效率,尤其是在处理大量数据时。此外,字典的使用也支持动态插入和删除操作,这在处理变动的数据集时非常有用。
是的,这里的逻辑正是意味着只有当圈的半径大于或等于玩具的半径时,玩具才可能被套中。这是因为如果圈的半径小于玩具的半径,即使圈的中心点正好位于玩具的中心点上,圈也无法完全覆盖玩具。因此,只有当圈的半径不小于玩具的半径时,我们才继续计算圈心到玩具心的距离是否小于或等于调整后的圈半径的平方(即 `d^2`),以判断玩具是否被套中。