Skip to content

Instantly share code, notes, and snippets.

@robmaceachern
Created January 25, 2012 00:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robmaceachern/1673869 to your computer and use it in GitHub Desktop.
Save robmaceachern/1673869 to your computer and use it in GitHub Desktop.
My point class
package com.robmaceachern.practice;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
/**
*
* @author Rob MacEachern rob@robmaceachern.com
*
* Thanks again Mark!
*
*/
public class Point implements Comparable<Point> {
public static final Point ORIGIN = new Point(0, 0);
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public double distanceTo(Point p) {
double distance = Math.sqrt(Math.pow(this.x - p.y, 2)
+ Math.pow(this.y - p.y, 2));
return distance;
}
@Override
public int compareTo(Point other) {
double thisDist = distanceTo(Point.ORIGIN);
double otherDist = other.distanceTo(Point.ORIGIN);
if (thisDist > otherDist) {
return 1;
} else if (thisDist < otherDist) {
return -1;
} else {
return 0;
}
}
public String toString() {
return String.format("(%d, %d)", x, y);
}
/**
* Returns the k {@code Point}s that are closest to the origin.
* @param arr an array of {@code Point}s
* @param k must be less than or equal to the size of the array
* @return the k elements closest to the origin (0,0).
*/
public static Point[] closestToOrigin(Point[] arr, int k){
if(k >= arr.length){
return Arrays.copyOf(arr, arr.length);
}
// our reverse comparator, since Java's priority queues have
// the 'least' element at the head, but we want the max at head.
Comparator<Point> reverseComparator = new Comparator<Point>(){
@Override
public int compare(Point a, Point b) {
return -a.compareTo(b);
}
};
// priority queue, with largest value at the head
PriorityQueue<Point> ret = new PriorityQueue<Point>(k+1, reverseComparator);
// we need to go through every element in arr
for(int i = 0; i < arr.length; i++){
// if have k elements in the queue so far,
// we'll need to see if we indeed need to add it or not.
// if we have less than k elements, it will be added regardless
if(ret.size() >= k){
// compare to the queue's head (largest)
// if it's smaller than the largest, it needs to be added
// peek is a constant time operation
if(arr[i].compareTo(ret.peek()) < 0){
// add the element. log n operation
ret.add(arr[i]);
// remove the largest remaining so we only keep k elements in queue
// log n operation
ret.poll();
}
} else {
ret.add(arr[i]);
}
}
return ret.toArray(new Point[ret.size()]);
}
/**
* A quick little demo.
*/
public static void main (String[] args){
Point[] points = {new Point(22,22), new Point(0,0), new Point(55,55), new Point(11,11), new Point(44,44), new Point(33,33)};
int k = 3;
Point[] closest = closestToOrigin(points, k);
System.out.print("The " + k + " elements closest to the origin are: ");
System.out.println(Arrays.toString(closest));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment