假设您在2D平面上有一个点阵列。点被定义为:
class Point {
public int x;
public int y;
Point(int _x, int _y) { x = _x; y = _y; }
}
如何在java中找到位于同一直线上的最大点数?
答案 0 :(得分:3)
对于数组中的每个点,计算此点与其他点之间的角度。使用hashMap计算具有相同角度的数量。预期时间O(n ^ 2)
伪代码
int result = 0;
for(int i = 0; i < data.length; i++){
HashMap<Double, Integer> map = new HashMap();
for(int j = 0; j < data.length; j++){
if(i == j)
continue;
double angle = calculateAngle(data[i], data[j]);
if(map.containsKey(slope)){
map.put(angle, map.get(slope) + 1);
}else{
map.put(angle, 1);
}
result = max(result, map.get(slope));
}
}
注意:正如NiklasB的评论中提到的那样,使用double会导致一些精度问题,特别是当我们需要比较这些浮动值时。我们可以通过使用NiklasB建议的Rational类来避免这种情况。 (或者不那么精确,使用this)
答案 1 :(得分:3)
这是Java中使用精确算术的解决方案:
import java.util.List;
import java.util.Map;
import java.util.HashMap;
public class Solver {
public int maxPointsOnLine(List<Point> points) {
int ans = 0;
Map<Line, Integer> lines = new HashMap<Line, Integer>();
for (Point a : points) {
int max = 0;
int same = 0;
lines.clear();
for (Point b : points) {
if (a.x == b.x && a.y == b.y) {
++same;
} else {
Line line = new Line(b.x - a.x, b.y - a.y);
Integer count = lines.get(line);
if (count == null) {
count = 0;
}
++count;
lines.put(line, count);
max = Math.max(max, count);
}
}
ans = Math.max(ans, same + max);
}
return ans;
}
static class Line {
final int dx;
final int dy;
Line(int dx, int dy) {
if (dy == 0) {
dx = Math.abs(dx);
}
else if (dy < 0) {
dx = -dx;
dy = -dy;
}
int gcd = gcd(Math.abs(dx), dy);
dx /= gcd;
dy /= gcd;
this.dx = dx;
this.dy = dy;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Line)) {
return false;
}
Line another = (Line)other;
return dx == another.dy && dy == another.dy;
}
@Override
public int hashCode() {
return 31 * dx + dy;
}
}
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
答案 2 :(得分:0)
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
class Solution {
public:
int maxPoints(vector<Point> &points) {
int n = points.size(); //number of the points
if (n<=2){return n;}
vector<double> k; //vector to store the slops for one point with all the other points
int res = 0;
for (int i=0;i<n;i++){ // for each point in the 2d plane
k.clear();
int dup = 1; // number of the duplicates with currrent point
for (int j=0;j<n;j++){
if (i!=j){ // for every other point
if (points[i].x-points[j].x==0){ // if the slope is a vertical line
if (points[i].y-points[j].y==0){ // if the point j is the same as point i
dup++;
}else{
k.push_back(99999); //store the vertical line to a specific slope
}
}else{ // if it is the regular slop between point i and j
k.push_back(10000*(points[i].y-points[j].y)/(points[i].x-points[j].x)); // store the slope
}
}
}
sort(k.begin(),k.end()); //sort the slopes for counting
int pp = 1; //number of points in the same line of the point i
if (k.size()==0){pp=0;}
for (int jj=1;jj<k.size();jj++){ //count pp
if (k[jj]==k[jj-1]){
pp++;
}else{
if (pp+dup>res){res=pp+dup;} // res = pp + the number of duplicates
pp = 1;
}
}
if (pp+dup>res){res = pp+dup;}
}
return res;
}
};