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 =
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
The idea is to check the distance between all pairs of points and store the minimum distance found.
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
using namespace std;
// Function to compute Euclidean distance between two points
double distance(const vector<double>& p1, const vector<double>& 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<double>>& 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<double>> points = {{-1, -2}, {0, 0}, {1, 2}, {2, 3}};
double res = minDistance(points);
cout << fixed << setprecision(6) << res << endl;
return 0;
}
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);
}
}
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 minDist
if __name__ == "__main__":
points = [[-1, -2], [0, 0], [1, 2], [2, 3]]
res = minDistance(points)
print(f"{res:.6f}")
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"));
}
}
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));
Output
1.414214
[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 anddrin the left and right subarrays, and setdas 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 dl and dr, we take:
d = min(dl , dr)
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.
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
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<Point>& 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<Point>& 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<Point>& Px, vector<Point>& 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<Point>& points) {
vector<Point> Px = points;
vector<Point> 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<Point> points = {
{2, 3}, {12, 30}, {40, 50},
{5, 1}, {12, 10}, {3, 4}
};
cout << fixed << setprecision(6);
cout << "Minimum distance = " << closest(points);
return 0;
}
#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;
}
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));
}
}
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_dist
# 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
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_dist
# 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
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)))
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));
}
}
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)