Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1828. Queries on Number of Points Inside a Circle - Leetcode Solution

Problem Description

Given a list of 2D points on the X-Y plane, and a set of queries where each query represents a circle (with a center and a radius), your task is to determine, for each query, how many points from the list lie inside or on the boundary of the circle.

  • The input consists of an array points where each element is a pair [x, y] representing a point's coordinates.
  • The queries array contains elements of the form [x_center, y_center, radius] representing the center and radius of a circle.
  • For each query, count the number of points that are inside or exactly on the perimeter of the circle.
  • Each point can be counted multiple times, i.e., for every query where it lies inside/on the circle.

Thought Process

The core of the problem is checking whether each point lies within a given circle for every query. The naive approach is to check every point against every query, which is simple but potentially inefficient for large inputs. We recognize that the mathematical way to check if a point (x, y) is inside a circle centered at (x_c, y_c) with radius r is to verify if the squared distance (x - x_c)^2 + (y - y_c)^2 is less than or equal to r^2.

Initially, one might consider optimizing by preprocessing or using spatial data structures, but given the constraints of the problem (modest input sizes in LeetCode), a direct approach is both correct and efficient enough. The main idea is to loop through each query and, for each, check every point.

Solution Approach

  • Step 1: Iterate through each query in the queries list.
  • Step 2: For each query, extract the center coordinates (x_c, y_c) and the radius r.
  • Step 3: For each point in points, calculate the squared distance to the query's center: dx = x - x_c, dy = y - y_c, and distance_squared = dx * dx + dy * dy.
  • Step 4: If distance_squared is less than or equal to r * r, the point is inside or on the circle. Increment a counter.
  • Step 5: After checking all points for a query, store the count in a result array.
  • Step 6: Return the result array after processing all queries.

This approach is straightforward and leverages the mathematical definition of a circle. No advanced data structures are needed due to manageable input sizes.

Example Walkthrough

Sample Input:

  • points = [[1,3],[3,3],[5,3],[2,2]]
  • queries = [[2,3,1],[4,3,1],[1,1,2]]

Processing Query 1: [2,3,1] (center: (2,3), radius: 1)

  • Point [1,3]: dx = -1, dy = 0, distance_squared = 1. 1 ≤ 1 ⇒ inside
  • Point [3,3]: dx = 1, dy = 0, distance_squared = 1. 1 ≤ 1 ⇒ inside
  • Point [5,3]: dx = 3, dy = 0, distance_squared = 9. 9 > 1 ⇒ outside
  • Point [2,2]: dx = 0, dy = -1, distance_squared = 1. 1 ≤ 1 ⇒ inside

Count: 3

Processing Query 2: [4,3,1] (center: (4,3), radius: 1)

  • Point [1,3]: dx = -3, dy = 0, distance_squared = 9. 9 > 1 ⇒ outside
  • Point [3,3]: dx = -1, dy = 0, distance_squared = 1. 1 ≤ 1 ⇒ inside
  • Point [5,3]: dx = 1, dy = 0, distance_squared = 1. 1 ≤ 1 ⇒ inside
  • Point [2,2]: dx = -2, dy = -1, distance_squared = 5. 5 > 1 ⇒ outside

Count: 2

Processing Query 3: [1,1,2] (center: (1,1), radius: 2)

  • Point [1,3]: dx = 0, dy = 2, distance_squared = 4. 4 ≤ 4 ⇒ inside
  • Point [3,3]: dx = 2, dy = 2, distance_squared = 8. 8 > 4 ⇒ outside
  • Point [5,3]: dx = 4, dy = 2, distance_squared = 20. 20 > 4 ⇒ outside
  • Point [2,2]: dx = 1, dy = 1, distance_squared = 2. 2 ≤ 4 ⇒ inside

Count: 2

Final Output: [3, 2, 2]

Time and Space Complexity

  • Brute-force Approach:
    • For each query, check every point. If there are Q queries and N points, the time complexity is O(Q * N).
    • Space complexity is O(1) extra (excluding the output), as we only use counters and the output array.
  • Optimized Approaches:
    • Spatial partitioning or range trees could reduce time for larger datasets, but are not necessary here due to input limits.
    • For this LeetCode problem, the brute-force approach is both simple and sufficient.

Summary

This problem is a classic application of coordinate geometry and brute-force checking. By leveraging the mathematical definition of a circle, we can efficiently determine if each point is within a given radius for each query. The straightforward approach is optimal given the problem constraints, and the solution demonstrates how simple math and iteration can solve real-world geometric queries effectively.

Code Implementation

class Solution:
    def countPoints(self, points, queries):
        result = []
        for x_c, y_c, r in queries:
            count = 0
            r2 = r * r
            for x, y in points:
                dx = x - x_c
                dy = y - y_c
                if dx * dx + dy * dy <= r2:
                    count += 1
            result.append(count)
        return result
      
class Solution {
public:
    vector<int> countPoints(vector<vector<int>>& points, vector<vector<int>>& queries) {
        vector<int> result;
        for (const auto& q : queries) {
            int x_c = q[0], y_c = q[1], r = q[2];
            int r2 = r * r;
            int count = 0;
            for (const auto& p : points) {
                int dx = p[0] - x_c;
                int dy = p[1] - y_c;
                if (dx * dx + dy * dy <= r2) {
                    count++;
                }
            }
            result.push_back(count);
        }
        return result;
    }
};
      
class Solution {
    public int[] countPoints(int[][] points, int[][] queries) {
        int[] result = new int[queries.length];
        for (int i = 0; i < queries.length; i++) {
            int x_c = queries[i][0], y_c = queries[i][1], r = queries[i][2];
            int r2 = r * r;
            int count = 0;
            for (int[] p : points) {
                int dx = p[0] - x_c;
                int dy = p[1] - y_c;
                if (dx * dx + dy * dy <= r2) {
                    count++;
                }
            }
            result[i] = count;
        }
        return result;
    }
}
      
var countPoints = function(points, queries) {
    let result = [];
    for (let [x_c, y_c, r] of queries) {
        let count = 0;
        let r2 = r * r;
        for (let [x, y] of points) {
            let dx = x - x_c;
            let dy = y - y_c;
            if (dx * dx + dy * dy <= r2) {
                count++;
            }
        }
        result.push(count);
    }
    return result;
};