Created
January 25, 2012 00:54
-
-
Save robmaceachern/1673869 to your computer and use it in GitHub Desktop.
My point class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.robmaceachern.practice; | |
import java.util.Arrays; | |
import java.util.Comparator; | |
import java.util.PriorityQueue; | |
/** | |
* | |
* @author Rob MacEachern [email protected] | |
* | |
* 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