1828. 统计一个圆中点的数目

【算法题解析】统计圆内点的数量 —— LeetCode 1828 “统计圆内点的数目”


题目描述

给你一个二维平面上的点集 points,其中每个点 points[i] = [x_i, y_i] 表示第 i 个点的坐标。注意,可能存在多个点坐标相同的情况。

同时给你一个查询列表 queries,其中每个查询 queries[j] = [x_j, y_j, r_j] 表示一个圆,圆心为 (x_j, y_j),半径为 r_j

请你对每个查询圆统计:有多少点位于该圆内或圆的边界上。最后返回一个数组 answer,其中 answer[j] 是第 j 个查询的答案。


解题分析

题目要求我们对于多个圆查询,统计这些圆内包含的点的个数。对每个查询圆,我们需要检查所有点,判断它们是否落在该圆内。

判断点 (x_i, y_i) 是否在以 (x_j, y_j) 为圆心、半径为 r_j 的圆内的条件是:

(xi−xj)2+(yi−yj)2≤rj2(x_i - x_j)^2 + (y_i - y_j)^2 \leq r_j^2(xixj)2+(yiyj)2rj2

满足该条件的点计数即为答案。


解决方案

方法一:暴力枚举

对每一个查询圆,遍历所有点,判断点是否在圆内,统计数量。

  • 步骤
    1. 初始化一个结果数组 answer
    2. 对于每个查询圆 (x_j, y_j, r_j)
      • 计算半径平方 r_j^2
      • 遍历所有点 (x_i, y_i)
        • 判断 (x_i - x_j)^2 + (y_i - y_j)^2 是否小于等于 r_j^2
        • 如果满足,计数器加一。
      • 将计数结果加入 answer
    3. 返回 answer
  • 代码示例(Python):
from typing import List

class Solution:
    def countPoints(self, points: List[List[int]], queries: List[List[int]]) -> List[int]:
        answer = []
        for xj, yj, rj in queries:
            count = 0
            r_sq = rj * rj
            for xi, yi in points:
                dx = xi - xj
                dy = yi - yj
                if dx * dx + dy * dy <= r_sq:
                    count += 1
            answer.append(count)
        return answer

复杂度分析

  • 时间复杂度:
    由于对每个查询,我们都遍历一遍所有点,时间复杂度为 O(Q * N),其中 Q 是查询数量,N 是点的数量。
  • 空间复杂度:
    除了存储输入和输出,空间开销为常数 O(1)

优化思路

当点和查询数量特别大时,暴力方法可能会超时。可采用空间数据结构进行优化,比如:

  • 空间划分结构:四叉树 (Quadtree)、KD 树等,用于快速查询空间范围内的点。
  • 离散化 + 预处理:在二维空间中对点坐标进行离散化,构建二维前缀和等辅助结构。

这些方法适合进阶使用,适合对大数据集进行快速查询。


示例说明

假设输入如下:

points = [[1,3],[3,3],[5,3],[2,2]]
queries = [[2,3,1],[4,3,1],[1,1,2]]
  • 对第一个查询圆 (2,3,1)
    • 半径平方为 1。
    • 检查每个点:
      • (1,3): 距离平方 (1-2)^2 + (3-3)^2 = 1 <= 1,计数 +1。
      • (3,3): 距离平方 1 <= 1,计数 +1。
      • (5,3): 距离平方 9 > 1,不计数。
      • (2,2): 距离平方 1 <= 1,计数 +1。
    • 结果:3 个点。
  • 对第二个查询圆 (4,3,1)
    • 半径平方为 1。
    • 检查点:
      • (1,3): 距离平方 9 > 1,不计数。
      • (3,3): 距离平方 1 <= 1,计数 +1。
      • (5,3): 距离平方 1 <= 1,计数 +1。
      • (2,2): 距离平方 5 > 1,不计数。
    • 结果:2 个点。
  • 对第三个查询圆 (1,1,2)
    • 半径平方为 4。
    • 检查点:
      • (1,3): 距离平方 4 <= 4,计数 +1。
      • (3,3): 距离平方 8 > 4,不计数。
      • (5,3): 距离平方 20 > 4,不计数。
      • (2,2): 距离平方 2 <= 4,计数 +1。
    • 结果:2 个点。

最终返回:

[3, 2, 2]

总结

本题是典型的空间查询问题,暴力解法直观且易实现,但在数据规模大时可能效率不足。合理利用空间数据结构可进一步优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值