algorithm
computational geometry
nearest neighbor search
spatial analysis
plane geometry

Fast algorithm to find the x closest points to a given point on a plane

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Finding the x closest points to a target point is a classic nearest-neighbor problem. The fastest practical solution depends on whether you have one query or many: for a single query over an unsorted list, a max-heap or quickselect approach is usually best; for repeated queries over a large point set, a spatial index such as a k-d tree is often more efficient.

Start with the Right Baseline

The naive solution is:

  1. compute the distance from the target to every point
  2. sort all distances
  3. take the first x

That works, but it costs O(n log n) because the full sort is more work than necessary if you only need the closest x points rather than a total ordering of all points.

A better one-shot approach is to keep only the best x candidates seen so far.

Use a Max-Heap for a Single Query

For one query over n points, a max-heap of size x gives a clean O(n log x) solution. The idea is:

  • compute squared distance for each point
  • keep a heap of at most x points
  • if a new point is closer than the current farthest in the heap, replace it

Using squared distance avoids an unnecessary square root because relative ordering is unchanged.

python
1import heapq
2
3
4def k_closest(points, target, k):
5    tx, ty = target
6    heap = []
7
8    for px, py in points:
9        dist2 = (px - tx) ** 2 + (py - ty) ** 2
10
11        if len(heap) < k:
12            heapq.heappush(heap, (-dist2, (px, py)))
13        elif dist2 < -heap[0][0]:
14            heapq.heapreplace(heap, (-dist2, (px, py)))
15
16    return [point for _, point in heap]
17
18
19points = [(1, 2), (5, 5), (0, 0), (2, 1), (10, 10)]
20print(k_closest(points, (0, 0), 3))

This is usually the best mix of speed and simplicity for a single query when k is much smaller than n.

Quickselect Can Be Even Faster on Average

If you want expected linear time for a one-off query, quickselect is another strong option. Instead of maintaining a heap, quickselect partitions the array around a pivot until the first k positions contain the k closest points.

The average time complexity is O(n), though the worst case is worse if the pivot choices are poor. In interview-style or performance-oriented settings, quickselect is often the answer people mean by "faster than sorting everything."

In production code, the heap solution is frequently easier to implement correctly and is already very good when k is relatively small.

Use a Spatial Index for Repeated Queries

If you need many nearest-neighbor queries against the same dataset, rebuilding a heap from scratch every time may be wasteful. In that case, preprocess the points into a k-d tree or another spatial index.

With SciPy, for example:

python
1import numpy as np
2from scipy.spatial import KDTree
3
4points = np.array([(1, 2), (5, 5), (0, 0), (2, 1), (10, 10)])
5tree = KDTree(points)
6
7distances, indices = tree.query((0, 0), k=3)
8print(points[indices])

This kind of structure pays off when the point set is reused for many target points. The preprocessing cost makes less sense when you only need one query.

That is the key design question:

  • one query: heap or quickselect
  • many queries: spatial index

Watch the Distance Metric and Data Size

Most plane-geometry problems use Euclidean distance, but some applications need Manhattan distance or a domain-specific metric. The algorithmic pattern stays similar, but the distance formula changes.

Also remember that if x is close to n, the benefit of a heap shrinks. When you need almost every point anyway, sorting or partial sorting may be good enough and easier to reason about.

For extremely large datasets or streaming inputs, the bounded max-heap approach is attractive because it only stores x candidate points at once rather than all distances.

Common Pitfalls

The biggest mistake is sorting the entire dataset when you only need the closest x points. That adds unnecessary work.

Another issue is computing the full Euclidean distance with square roots inside the loop. For comparison purposes, squared distance is enough and cheaper.

Developers also sometimes build a k-d tree for a one-off query. That preprocessing cost usually makes sense only when the same point set will be queried repeatedly.

Finally, be clear about ties and output order. A heap gives you the correct set of closest points, but not necessarily in sorted nearest-to-farthest order unless you sort the final result separately.

Summary

  • For a single query, a max-heap of size x gives an efficient O(n log x) solution.
  • Quickselect can improve the expected time to O(n) for one-off selection.
  • For repeated queries on the same points, a k-d tree or similar spatial index is often better.
  • Use squared distance when only relative closeness matters.
  • The best algorithm depends on whether the dataset is static, how many queries you have, and how large x is compared with n.

Course illustration
Course illustration

All Rights Reserved.