The Question statement is as follows:
Find the K closest points to the origin in a 2D plane, given an array containing N points.The output must be in non decreasing order.
Solution: I have solved this using comparator and priority queue and my code looks like below:
class Point {
double x;
double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
}
public class KClosestPoints {
public Point[] getKNearestPoints(Point[] points, int k) {
if (k == 0 || points.length == 0) {
return new Point[0];
}
Point[] rValue = new Point[k];
int index = k - 1;
if (points.length < k) {
index = points.length - 1;
}
final Point org = new Point(0, 0);
PriorityQueue<Point> pq = new PriorityQueue<Point>(k,
new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
Double d2 = getDistance(o2, org);
Double d1 = getDistance(o1, org);
if (d2 > d1) {
return 1;
} else if (d2 < d1) {
return -1;
} else
return 0;
}
});
for (int i = 0; i < points.length; i++) {
pq.offer(points[i]);
if (pq.size() > k) {
pq.poll();
}
}
while (!pq.isEmpty()) {
rValue[index] = pq.poll();
index--;
}
return rValue;
}
private static double getDistance(Point a, Point b) {
return Math.sqrt(((a.x - b.x) * (a.x - b.x))
+ ((a.y - b.y) * (a.y - b.y)));
}
My Code works for all test cases i have used except this:
test6[0] = new Point(Double.MIN_VALUE, Double.MAX_VALUE);
test6[1] = new Point(Double.MIN_VALUE, Double.MIN_VALUE);
test6[2] = new Point(Double.MAX_VALUE, Double.MAX_VALUE);
getKNearestPoints(test6, 2);
The answer should be test6[0] and test6[1] whereas this code gives answer as test6[0] and test6[2]. Help me in finding the issue.
EDIT: Later i have noticed it is giving wrong answer in all the test cases with k = 2 when the points are are positive and negative and one such test case is mentioned above
For the issue you are asking, there is a problem calculating the distance:
Note:
Double.MIN_VALUE
is a positive number.Now the euclidean distance
d = Math.sqrt(((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y)));
returnInfinity
when calculating distance betweenPoint # 0
andPoint # 1
, and betweenPoint # 0
andPoint # 3
, because:Point # 1
After getting the distance of
Point # 1
andPoint # 0
(Infinity
), and then comparing it with the distance ofPoint # 3
andPoint # 0
(AlsoInfinity
) thenInfinity = Infinity
istrue
, hence theComparator
says "Both Points are equal", and thePriorityQueue
don't order as you wish.For the operation with
Double.MAX_VALUE
you must not useDouble
, instead useBigDecimal
:Why are we not calculating the real distance with square root? Because:
a > b
thensqrt(a) > sqrt(b)
, its proportional, so it's enough get the value without apply square root function.Taking advantage of
BigDecimal
, it implements its ownComparator
so we use it in thecompareTo
method of theComparator
defined: