Given an array of N points in the plane, the task is to find a pair of points with the smallest distance between them, where the distance between two points (x1, y1) and (x2, y2) can be calculated as [(x1 - x2) ^ 2] + [(y1 - y2) ^ 2].
Examples:
Input: P[] = { {1, 2}, {2, 3}, {3, 4}, {5, 6}, {2, 1} } Output: The smallest distance is 2. Explanation: Distance between points as: P[0] and P[1] = 2, P[0] and P[2] = 8, P[0] and P[3] = 32, P[0] and P[4] = 2 P[1] and P[2] = 2, P[1] and P[3] = 18, P[1] and P[4] = 4 P[2] and P[3] = 8, P[2] and P[4] = 10 P[3] and P[4] = 34 Minimum distance among them all is 2.
Input: P[] = { {0, 0}, {2, 1}, {1, 1} } Output: The smallest distance is 1.
Approach: To solve the problem follow the below idea:
The idea is to use Sweep Line Algorithm to find the smallest distance between a pair of points. We can sort the points on the basis of their x-coordinates and start iterating over all the points in increasing order of their x-coordinates.
Suppose we are at the Kth point so all the points to the left of Kth point will be already processed. Let the minimum distance between 2 points found so far be D. So, to process the Kth point, we will consider only those points whose distance from Kth point < D. Maintain a set to store the previously processed points whose x-coordinates are less than D distance from Kth point. All the points in the set are ordered by their y-coordinates. In the below image, the light-green shaded region represents all the points which are available in the set.
Now to search for the points in the set which are less than D distance away from point K, we will consider only those points whose y-coordinates are less than D distance from Kth point (points having their y-coordinates in range (YK - D, YK + D)). This can be performed in O(logN) time using Binary Search on set. Iterate over all those points and if distance is less than D, then update the minimum distance. In the above image, the dark-green region represents all the points in the set whose y-coordinates are less than D distance from Kth point. The efficiency of the algorithm is based on the fact that this region will contain O(1) points on an average.
After iterating over all the points, return the smallest distance found between any 2 points.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>usingnamespacestd;// To find the closest pair of pointslonglongclosestPair(vector<pair<longlong,longlong>>coordinates,intn){// Sort points according to x-coordinatessort(coordinates.begin(),coordinates.end());// Set to store already processed points whose distance// from the current points is less than the smaller// distance so farset<pair<longlong,longlong>>s;longlongsquaredDistance=LLONG_MAX;longlongj=0;for(longlongi=0;i<n;++i){// Find the value of DlonglongD=ceil(sqrt(squaredDistance));while(coordinates[i].first-coordinates[j].first>=D){s.erase({coordinates[j].second,coordinates[j].first});j+=1;}// Find the first point in the set whose y-coordinate is less than D distance from ith point autostart=s.lower_bound({coordinates[i].second-D,coordinates[i].first});// Find the last point in the set whose y-coordinate is less than D distance from ith point autoend=s.upper_bound({coordinates[i].second+D,coordinates[i].first});// Iterate over all such points and update the minimum distancefor(autoit=start;it!=end;++it){longlongdx=coordinates[i].first-it->second;longlongdy=coordinates[i].second-it->first;squaredDistance=min(squaredDistance,1LL*dx*dx+1LL*dy*dy);}// Insert the point as {y-coordinate, x-coordinate}s.insert({coordinates[i].second,coordinates[i].first});}returnsquaredDistance;}// Driver codeintmain(){// Points on a plane P[i] = {x, y}vector<pair<longlong,longlong>>P={{1,2},{2,3},{3,4},{5,6},{2,1}};intn=P.size();// Function callcout<<"The smallest distance is "<<closestPair(P,n);return0;}
Java
importjava.util.*;publicclassClosestPair{// To find the closest pair of pointspublicstaticlongclosestPair(List<long[]>coordinates,intn){// Sort points according to x-coordinatesCollections.sort(coordinates,Comparator.comparingLong(a->a[0]));// TreeSet to store already processed points whose distance// from the current points is less than the smallest distance so farTreeSet<long[]>set=newTreeSet<>(Comparator.comparingLong(a->a[1]));longsquaredDistance=Long.MAX_VALUE;intj=0;for(inti=0;i<n;++i){// Find the value of DlongD=(long)Math.ceil(Math.sqrt(squaredDistance));while(coordinates.get(i)[0]-coordinates.get(j)[0]>=D){set.remove(newlong[]{coordinates.get(j)[1],coordinates.get(j)[0]});j+=1;}// Find the first point in the set whose y-coordinate is less than D distance from ith pointlong[]lowerBound=newlong[]{coordinates.get(i)[1]-D,Long.MIN_VALUE};// Find the last point in the set whose y-coordinate is less than D distance from ith pointlong[]upperBound=newlong[]{coordinates.get(i)[1]+D,Long.MAX_VALUE};// Iterate over all such points and update the minimum distancefor(long[]point:set.subSet(lowerBound,upperBound)){longdx=coordinates.get(i)[0]-point[1];longdy=coordinates.get(i)[1]-point[0];squaredDistance=Math.min(squaredDistance,dx*dx+dy*dy);}// Insert the point as {y-coordinate, x-coordinate}set.add(newlong[]{coordinates.get(i)[1],coordinates.get(i)[0]});}returnsquaredDistance;}publicstaticvoidmain(String[]args){// Points on a plane P[i] = {x, y}List<long[]>P=newArrayList<>();P.add(newlong[]{1,2});P.add(newlong[]{2,3});P.add(newlong[]{3,4});P.add(newlong[]{5,6});P.add(newlong[]{2,1});intn=P.size();// Function callSystem.out.println("The smallest distance is "+closestPair(P,n));}}
Python
importmathfromsortedcontainersimportSortedSet# Point class for 2-D pointsclassPoint:def__init__(self,x,y):self.x=xself.y=ydefclosestPair(coordinates,n):# Sort points according to x-coordinatescoordinates.sort(key=lambdap:p.x)# SortedSet to store already processed points whose distance# from the current points is less than the smaller distance so fars=SortedSet(key=lambdap:(p.y,p.x))squaredDistance=1e18j=0foriinrange(len(coordinates)):# Find the value of DD=math.ceil(math.sqrt(squaredDistance))whilej<=iandcoordinates[i].x-coordinates[j].x>=D:s.discard(Point(coordinates[j].x,coordinates[j].y))j+=1# Find the first point in the set whose y-coordinate is less than D distance from ith pointstart=Point(coordinates[i].x,coordinates[i].y-D)# Find the last point in the set whose y-coordinate is less than D distance from ith pointend=Point(coordinates[i].x,coordinates[i].y+D)# Iterate over all such points and update the minimum distanceforitins.irange(start,end):dx=coordinates[i].x-it.xdy=coordinates[i].y-it.ysquaredDistance=min(squaredDistance,dx*dx+dy*dy)# Insert the point into the SortedSets.add(Point(coordinates[i].x,coordinates[i].y))returnsquaredDistance# Driver codeif__name__=="__main__":# Points on a plane P[i] = {x, y}P=[Point(1,2),Point(2,3),Point(3,4),Point(5,6),Point(2,1)]n=5# Function callprint("The smallest distance is",closestPair(P,n))
JavaScript
// To find the closest pair of pointsfunctionclosestPair(coordinates){// Sort points according to x-coordinatescoordinates.sort((a,b)=>a[0]-b[0]);// Array to store already processed pointslets=[];letsquaredDistance=Number.MAX_SAFE_INTEGER;letj=0;for(leti=0;i<coordinates.length;++i){// Find the value of DletD=Math.ceil(Math.sqrt(squaredDistance));// Remove points from the set that are too far from the current pointwhile(coordinates[i][0]-coordinates[j][0]>=D){s.shift();j+=1;}// Find points within the range [coordinates[i][1] - D, coordinates[i][1] + D]letstart=coordinates[i][1]-D;letend=coordinates[i][1]+D;// Iterate over all such points and update the minimum distancefor(letk=0;k<s.length;++k){letdx=coordinates[i][0]-s[k][1];letdy=coordinates[i][1]-s[k][0];squaredDistance=Math.min(squaredDistance,dx*dx+dy*dy);}// Insert the point into the sets.push([coordinates[i][1],coordinates[i][0]]);}returnsquaredDistance;}// Driver codefunctionmain(){// Points on a plane P[i] = [x, y]letP=[[1,2],[2,3],[3,4],[5,6],[2,1]];// Function callconsole.log("The smallest distance is",closestPair(P));}// Call main functionmain();
Output
The smallest distance is 2
Time Complexity: O(N * logN), because we iterate over all the N points and logN for binary search to find the points whose Y coordinates are less than D distance away from the current point where D is the minimum distance between any two points covered so far. Auxiliary Space: O(N)