Minimum Distance between Two Points (original) (raw)
You are given an array of n distinct points in a 2D plane, where each point is represented by its coordinates (x , y). Now find the **minimum Euclidean distance between any **two distinct points.
**Note: For two points A(px, qx) and B(py, qy) the distance Euclidean between them is:
Distance = \sqrt{(p_{x}-q_{x})^{2}+ (p_{y}-q_{y})^{2}}
**Examples:
**Input: arr[] = [[ -1, -2 ], [ 0, 0 ], [ 1, 2 ], [ 2, 3 ]]
**Output: 1.414214
**Explanation: The smallest distance is between points (1, 2) and (2, 3), which is 1.414214.**Input: arr[] = [[ -2, -2 ], [ 1, 2 ], [ -1, 0 ], [ 3, 3 ]]
**Output: 2.236068
**Explanation: The smallest distance is between points (-2, -2) and (-1, 0), which is 2.236068.
Table of Content
- [Naive Approach] Checking All Pairs - O(n^2) Time and O(1) Space
- [Expected Approach] Using Divide and Conquer – O(n log n) Time and O(n) Space
[Naive Approach] Checking All Pairs - O(n^2) Time and O(1) Space
The idea is to check the distance between all pairs of points and store the minimum distance found.
C++ `
#include #include #include #include
using namespace std;
// Function to compute Euclidean distance between two points double distance(const vector& p1, const vector& p2) { return sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1])); }
// Function that returns the smallest distance // between any pair of points double minDistance(const vector<vector>& points) { int n = points.size();
double minDist = 1e9;
// Brute force to check all pairs
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
double dist = distance(points[i], points[j]);
if (dist < minDist) {
minDist = dist;
}
}
}
// Return the smallest distance
return minDist; }
int main() { vector<vector> points = {{-1, -2}, {0, 0}, {1, 2}, {2, 3}};
double res = minDistance(points);
cout << fixed << setprecision(6) << res << endl;
return 0;}
Java
import java.util.ArrayList; import java.util.List; import java.lang.Math;
class GfG {
// Function to compute Euclidean distance between two points
static double distance(double[] p1, double[] p2) {
return Math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) +
(p1[1] - p2[1]) * (p1[1] - p2[1]));
}
// Function that returns the smallest distance
// between any pair of points
static double minDistance(List<double[]> points) {
int n = points.size();
double minDist = Double.MAX_VALUE;
// Brute force to check all pairs
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
double dist = distance(points.get(i), points.get(j));
if (dist < minDist) {
minDist = dist;
}
}
}
// Return the smallest distance
return minDist;
}
public static void main(String[] args) {
List<double[]> points = new ArrayList<>();
points.add(new double[]{-1, -2});
points.add(new double[]{0, 0});
points.add(new double[]{1, 2});
points.add(new double[]{2, 3});
double res = minDistance(points);
System.out.printf("%.6f\n", res);
}}
Python
import math
Function to compute Euclidean distance between two points
def distance(p1, p2): return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
Function that returns the smallest distance
between any pair of points
def minDistance(points): n = len(points)
minDist = float('inf')
# Brute force to check all pairs
for i in range(n):
for j in range(i + 1, n):
dist = distance(points[i], points[j])
if dist < minDist:
minDist = dist
# Return the smallest distance
return minDistif name == "main": points = [[-1, -2], [0, 0], [1, 2], [2, 3]]
res = minDistance(points)
print(f"{res:.6f}")C#
using System; using System.Collections.Generic;
class GfG {
// Function to compute Euclidean distance between two points
static double distance(double[] p1, double[] p2) {
return Math.Sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) +
(p1[1] - p2[1]) * (p1[1] - p2[1]));
}
// Function that returns the smallest distance
// between any pair of points
static double minDistance(List<double[]> points) {
int n = points.Count;
double minDist = double.MaxValue;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
double dist = distance(points[i], points[j]);
if (dist < minDist) {
minDist = dist;
}
}
}
// Return the smallest distance
return minDist;
}
static void Main() {
List<double[]> points = new List<double[]> {
new double[] {-1, -2},
new double[] {0, 0},
new double[] {1, 2},
new double[] {2, 3}
};
double res = minDistance(points);
Console.WriteLine(res.ToString("F6"));
}}
JavaScript
function distance(p1, p2) { return Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2); }
// Function that returns the smallest distance // between any pair of points function minDistance(points) { let n = points.length; let minDist = Infinity;
for (let i = 0; i < n; ++i) {
for (let j = i + 1; j < n; ++j) {
let dist = distance(points[i], points[j]);
if (dist < minDist) {
minDist = dist;
}
}
}
// Return the smallest distance
return minDist;}
// Driver Code const points = [[-1, -2], [0, 0], [1, 2], [2, 3]]; const res = minDistance(points);
console.log(res.toFixed(6));
`
[Expected Approach] Using Divide and Conquer – O(n log n) Time and O(n) Space
The idea is to use the divide and conquer technique, where the given points are recursively divided into two We compute the minimum distance in the left and right halves separately, and then check for closer pairs that lie across the dividing line.
**Step By Step Implementation:
- **Sort the points by x-coordinate.
- **Recursively divide the points into left and right subarrays until each subarrays has one or two points:
- If one point, return infinity.
- If two points, return their distance.
- Find the minimum distances
dl anddr **``**in the left and right subarrays, and set **d**as the smaller value betweendl anddr.

- Build a strip: Include points with x-distance ≤ d from midline

- Sort the strip by y-coordinate.
- For each point in the strip, Compare each point with next ≤ 7 points.
- Update minimum distance****,** if a smaller distance is found in the strip.
- Return the minimum among the left half, right half, or across the strip.
**Key Insights:
After dividing the points into two halves and computing the minimum distances **d land **d r, we take:
**d = min(d l ****, d** r )
Now, instead of checking all cross-pairs, we only focus on points **near the dividing line, as only these can form a closer pair. We stores all points whose **x-distance from the dividing point is ≤
d, i.e., points betweenx - dandx + d. So, all these points lie inside a vertical strip of **width2dalong the x-axis.
- **Why do we consider only points within distance d from the mid line?
To efficiently find the closest pair across the dividing line, we only consider points that lie within a distance **d from the midline. Specifically, we collect all points whose x-coordinate lies between **x − d and **x + d , forming a vertical strip of width **2d. This is because if two points are farther than d apart in the x-direction, their overall Euclidean distance will already be greater than d, so they cannot form a closer pair and can be safely ignored.
- **Why do we sort by y?
Sorting the strip by y-coordinate allows us to compare only nearby points in the vertical direction. This helps reduce unnecessary comparisons and ensures efficiency in the merging step.
- **Why are at most 7 comparisons needed for each point?
The **2d × d rectangle can be divided into two **d × d squares, and each of these can be further divided into four smaller squares of size **d / 2 × d / 2.
- The diagonal of these smaller squares (d/2 x d/2) is less than
d/√2 which is less than d, so **no two points can occupy the same small square (otherwise, they’d be closer thand, violating the earlier recursive result).- So, **each
d × dsquare can have at most 4 points, totaling **at most 8 points in the full2d × drectangle.Since we’re only comparing the current point with the others, that means **at most 7 valid comparisons.
C++ `
#include #include #include #include using namespace std;
struct Point { double x, y; };
// Function to calculate distance between two points double dist(Point p1, Point p2) { return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); }
// Brute force approach for small number of points double bruteForce(vector& pts, int l, int r) { double minDist = DBL_MAX;
for (int i = l; i < r; i++)
for (int j = i + 1; j < r; j++)
minDist = min(minDist, dist(pts[i], pts[j]));
return minDist;}
// A utility function to find the distance between the closest points of // strip of a given size. All points in strip[] are sorted according to // y coordinate. They all have an upper bound on minimum distance as d. // Note that this method seems to be a O(n^2) method, but it's a O(n) // method as the inner loop runs at most 6 times double stripClosest(vector& strip, double d) { double minDist = d; int n = strip.size();
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n &&
(strip[j].y - strip[i].y) < minDist; j++) {
minDist = min(minDist, dist(strip[i], strip[j]));
}
}
return minDist;}
// A recursive function to find the smallest distance. The array Px contains // all points sorted according to x coordinates and Py contains all points // sorted according to y coordinates double closestUtil(vector& Px, vector& Py) { int n = Px.size();
if (n <= 3)
return bruteForce(Px, 0, n);
int mid = n / 2;
Point midPoint = Px[mid];
vector<Point> Pxl(Px.begin(), Px.begin() + mid);
vector<Point> Pxr(Px.begin() + mid, Px.end());
vector<Point> Pyl, Pyr;
for (auto& p : Py) {
if (p.x <= midPoint.x)
Pyl.push_back(p);
else
Pyr.push_back(p);
}
double dl = closestUtil(Pxl, Pyl);
double dr = closestUtil(Pxr, Pyr);
double d = min(dl, dr);
vector<Point> strip;
for (auto& p : Py) {
if (abs(p.x - midPoint.x) < d)
strip.push_back(p);
}
return min(d, stripClosest(strip, d));}
// Main function double closest(vector& points) { vector Px = points; vector Py = points;
sort(Px.begin(), Px.end(), [](Point a, Point b) {
return a.x < b.x;
});
sort(Py.begin(), Py.end(), [](Point a, Point b) {
return a.y < b.y;
});
return closestUtil(Px, Py);}
// Driver code int main() { vector points = { {2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4} };
cout << fixed << setprecision(6);
cout << "Minimum distance = " << closest(points);
return 0;}
C
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <float.h>
typedef struct { double x, y; } Point;
// Distance between two points double dist(Point a, Point b) { return sqrt((a.x - b.x)(a.x - b.x) + (a.y - b.y)(a.y - b.y)); }
// Brute force double bruteForce(Point pts[], int n) { double min = DBL_MAX; for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) if (dist(pts[i], pts[j]) < min) min = dist(pts[i], pts[j]); return min; }
// Compare by x int cmpX(const void* a, const void* b) { return ((Point*)a)->x - ((Point*)b)->x; }
// Compare by y int cmpY(const void* a, const void* b) { return ((Point*)a)->y - ((Point*)b)->y; }
// A utility function to find the distance between the closest points of // strip of a given size. All points in strip[] are sorted according to // y coordinate. They all have an upper bound on minimum distance as d. // Note that this method seems to be a O(n^2) method, but it's a O(n) // method as the inner loop runs at most 6 times double stripClosest(Point strip[], int size, double d) { double min = d; qsort(strip, size, sizeof(Point), cmpY);
for (int i = 0; i < size; i++)
for (int j = i + 1; j < size &&
(strip[j].y - strip[i].y) < min; j++)
if (dist(strip[i], strip[j]) < min)
min = dist(strip[i], strip[j]);
return min;}
// A recursive function to find the smallest distance. The array Px contains // all points sorted according to x coordinates and Py contains all points // sorted according to y coordinates double closestUtil(Point pts[], int n) { if (n <= 3) return bruteForce(pts, n);
int mid = n / 2;
Point midPoint = pts[mid];
double dl = closestUtil(pts, mid);
double dr = closestUtil(pts + mid, n - mid);
double d = fmin(dl, dr);
Point strip[n];
int j = 0;
for (int i = 0; i < n; i++)
if (fabs(pts[i].x - midPoint.x) < d)
strip[j++] = pts[i];
return fmin(d, stripClosest(strip, j, d));}
// Main function to call algorithm double closest(Point pts[], int n) { qsort(pts, n, sizeof(Point), cmpX); return closestUtil(pts, n); }
// Driver code int main() { Point pts[] = { {2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4} };
int n = sizeof(pts) / sizeof(pts[0]);
printf("Minimum distance = %.6lf\n", closest(pts, n));
return 0;}
Java
import java.util.*;
class Point { double x, y; Point(double x, double y) { this.x = x; this.y = y; } }
public class GfG {
// Distance between two points
static double dist(Point a, Point b) {
return Math.sqrt((a.x - b.x) * (a.x - b.x) +
(a.y - b.y) * (a.y - b.y));
}
// Brute force for small cases
static double bruteForce(List<Point> pts) {
double min = Double.MAX_VALUE;
for (int i = 0; i < pts.size(); i++)
for (int j = i + 1; j < pts.size(); j++)
min = Math.min(min, dist(pts.get(i), pts.get(j)));
return min;
}
// A utility function to find the distance between the closest points of
// strip of a given size. All points in strip[] are sorted according to
// y coordinate. They all have an upper bound on minimum distance as d.
// Note that this method seems to be a O(n^2) method, but it's a O(n)
// method as the inner loop runs at most 6 times
static double stripClosest(List<Point> strip, double d) {
double min = d;
strip.sort(Comparator.comparingDouble(p -> p.y));
for (int i = 0; i < strip.size(); i++)
for (int j = i + 1; j < strip.size() &&
(strip.get(j).y - strip.get(i).y) < min; j++)
min = Math.min(min, dist(strip.get(i), strip.get(j)));
return min;
}
// A recursive function to find the smallest distance. The array Px contains
// all points sorted according to x coordinates and Py contains all points
// sorted according to y coordinates
static double closestUtil(List<Point> pts) {
int n = pts.size();
if (n <= 3) return bruteForce(pts);
int mid = n / 2;
Point midPoint = pts.get(mid);
double dl = closestUtil(pts.subList(0, mid));
double dr = closestUtil(pts.subList(mid, n));
double d = Math.min(dl, dr);
List<Point> strip = new ArrayList<>();
for (Point p : pts)
if (Math.abs(p.x - midPoint.x) < d)
strip.add(p);
return Math.min(d, stripClosest(strip, d));
}
static double closest(List<Point> points) {
points.sort(Comparator.comparingDouble(p -> p.x));
return closestUtil(points);
}
// Driver code
public static void main(String[] args) {
List<Point> points = Arrays.asList(
new Point(2, 3), new Point(12, 30),
new Point(40, 50), new Point(5, 1),
new Point(12, 10), new Point(3, 4)
);
System.out.printf("Minimum distance = %.6f\n", closest(points));
}}
Python
import math
Distance between two points
def dist(p1, p2): return math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
Brute force
def brute_force(points): min_dist = float('inf') n = len(points)
for i in range(n):
for j in range(i + 1, n):
min_dist = min(min_dist, dist(points[i], points[j]))
return min_distA utility function to find the distance between the closest points of
strip of a given size. All points in strip[] are sorted according to
y coordinate. They all have an upper bound on minimum distance as d.
Note that this method seems to be a O(n^2) method, but it's a O(n)
method as the inner loop runs at most 6 times
def strip_closest(strip, d): min_dist = d strip.sort(key=lambda p: p[1])
for i in range(len(strip)):
for j in range(i + 1, len(strip)):
if strip[j][1] - strip[i][1] >= min_dist:
break
min_dist = min(min_dist, dist(strip[i], strip[j]))
return min_distA recursive function to find the smallest distance. The array Px contains
all points sorted according to x coordinates and Py contains all points
sorted according to y coordinates
def closest_util(points): n = len(points)
if n <= 3:
return brute_force(points)
mid = n // 2
mid_point = points[mid]
dl = closest_util(points[:mid])
dr = closest_util(points[mid:])
d = min(dl, dr)
strip = [p for p in points if abs(p[0] - mid_point[0]) < d]
return min(d, strip_closest(strip, d))def closest(points): points.sort() return closest_util(points)
Driver code
points = [(2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (3, 4)]
print("Minimum distance = {:.6f}".format(closest(points)))
C#
using System; using System.Collections.Generic;
class Point { public double x, y; public Point(double x, double y) { this.x = x; this.y = y; } }
class GfG {
static double Dist(Point a, Point b) {
return Math.Sqrt((a.x - b.x)*(a.x - b.x) +
(a.y - b.y)*(a.y - b.y));
}
static double BruteForce(List<Point> pts) {
double min = double.MaxValue;
for (int i = 0; i < pts.Count; i++)
for (int j = i + 1; j < pts.Count; j++)
min = Math.Min(min, Dist(pts[i], pts[j]));
return min;
}
// A utility function to find the distance between the closest points of
// strip of a given size. All points in strip[] are sorted according to
// y coordinate. They all have an upper bound on minimum distance as d.
// Note that this method seems to be a O(n^2) method, but it's a O(n)
// method as the inner loop runs at most 6 times
static double StripClosest(List<Point> strip, double d) {
double min = d;
strip.Sort((a, b) => a.y.CompareTo(b.y));
for (int i = 0; i < strip.Count; i++)
for (int j = i + 1; j < strip.Count &&
(strip[j].y - strip[i].y) < min; j++)
min = Math.Min(min, Dist(strip[i], strip[j]));
return min;
}
// A recursive function to find the smallest distance. The array Px contains
// all points sorted according to x coordinates and Py contains all points
// sorted according to y coordinates
static double ClosestUtil(List<Point> pts) {
int n = pts.Count;
if (n <= 3) return BruteForce(pts);
int mid = n / 2;
Point midPoint = pts[mid];
double dl = ClosestUtil(pts.GetRange(0, mid));
double dr = ClosestUtil(pts.GetRange(mid, n - mid));
double d = Math.Min(dl, dr);
List<Point> strip = new List<Point>();
foreach (var p in pts)
if (Math.Abs(p.x - midPoint.x) < d)
strip.Add(p);
return Math.Min(d, StripClosest(strip, d));
}
static double Closest(List<Point> points) {
points.Sort((a, b) => a.x.CompareTo(b.x));
return ClosestUtil(points);
}
// Driver code
static void Main() {
List<Point> points = new List<Point> {
new Point(2, 3), new Point(12, 30),
new Point(40, 50), new Point(5, 1),
new Point(12, 10), new Point(3, 4)
};
Console.WriteLine("Minimum distance = {0:F6}", Closest(points));
}}
JavaScript
class Point { constructor(x, y) { this.x = x; this.y = y; } }
// Distance function function dist(a, b) { return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2); }
// Brute force function bruteForce(points) { let min = Infinity;
for (let i = 0; i < points.length; i++) { for (let j = i + 1; j < points.length; j++) { min = Math.min(min, dist(points[i], points[j])); } } return min; }
// A utility function to find the distance between the closest points of // strip of a given size. All points in strip[] are sorted according to // y coordinate. They all have an upper bound on minimum distance as d. // Note that this method seems to be a O(n^2) method, but it's a O(n) // method as the inner loop runs at most 6 times function stripClosest(strip, d) { let min = d; strip.sort((a, b) => a.y - b.y);
for (let i = 0; i < strip.length; i++) { for (let j = i + 1; j < strip.length && (strip[j].y - strip[i].y) < min; j++) { min = Math.min(min, dist(strip[i], strip[j])); } } return min; }
// A recursive function to find the smallest distance. The array Px contains // all points sorted according to x coordinates and Py contains all points // sorted according to y coordinates function closestUtil(points) { if (points.length <= 3) return bruteForce(points);
let mid = Math.floor(points.length / 2); let midPoint = points[mid];
let dl = closestUtil(points.slice(0, mid)); let dr = closestUtil(points.slice(mid));
let d = Math.min(dl, dr);
let strip = points.filter(p => Math.abs(p.x - midPoint.x) < d );
return Math.min(d, stripClosest(strip, d)); }
function closest(points) { points.sort((a, b) => a.x - b.x); return closestUtil(points); }
// Driver code let points = [ new Point(2, 3), new Point(12, 30), new Point(40, 50), new Point(5, 1), new Point(12, 10), new Point(3, 4) ];
console.log("Minimum distance = " + closest(points).toFixed(6));
`
Output
Minimum distance = 1.414214
**Applications:
- Used to detect planes that are too close to each other, helping prevent potential collisions.
- Used in motion planning to avoid obstacles by identifying the closest points in a robot’s path.
- Helps in data classification and pattern recognition by finding nearest data points.
- Used in optimizing placement of devices by identifying nearest neighbors for better communication.
**Time Complexity:
- Let the time complexity of the algorithm be T(n).
- The algorithm divides the set of points into two halves -> 2T(n/2)
- Building the strip takes -> O(n)
- Dividing the Py[] array takes -> O(n)
- Processing the strip takes -> O(n)
So, the recurrence relation becomes:
T(n) = 2T ( n / 2)+ O(n)+ O(n)+ O(n)
T(n) = 2T ( n / 2) + O(n)
T(n)= O(n logn)
**Auxiliary Space : O(n) (for storing Px[], Py[], and strip arrays)