Java 查找二维平面中位于同一直线上的最大点数
这“给定二维平面上的n个点,求出位于同一直线上的最大点数。” 来自leetcode.com的问题我正试图解决它,但我无法通过所有测试 案例 我试图做的是:-我使用一个hashmap,它的关键是角度b/w,我通过斜率的倒数得到的点,我存储每个斜率的值,最初是该点的不发生值,然后增加它 我正在使用另一个hashmap来计算点的发生率 我没有得到像(0,0),(1,0)这样的点的正确答案,它应该返回2,但它返回1 我错过了什么 我的代码是:Java 查找二维平面中位于同一直线上的最大点数,java,algorithm,Java,Algorithm,这“给定二维平面上的n个点,求出位于同一直线上的最大点数。” 来自leetcode.com的问题我正试图解决它,但我无法通过所有测试 案例 我试图做的是:-我使用一个hashmap,它的关键是角度b/w,我通过斜率的倒数得到的点,我存储每个斜率的值,最初是该点的不发生值,然后增加它 我正在使用另一个hashmap来计算点的发生率 我没有得到像(0,0),(1,0)这样的点的正确答案,它应该返回2,但它返回1 我错过了什么 我的代码是: public class MaxPointsINLine {
public class MaxPointsINLine {
int max = 0;
int same;
public int maxPoints(Point[] points) {
int max = 0;
Map<Double, Integer> map = new HashMap<Double, Integer>();
Map<Point, Integer> pointmap = new HashMap<Point, Integer>();
for(Point point: points)
{
if(!pointmap.containsKey(point))
{
pointmap.put(point, 1);
}
else
{
pointmap.put(point, pointmap.get(point)+1);
}
}
if (points.length >= 2) {
for (int i = 0; i < points.length; i++) {
for (int j = i ; j < points.length; j++) {
double dx = points[j].x - points[i].x;
double dy = points[j].y - points[i].y;
double slope = Math.atan(dy / dx);
if (!map.containsKey(slope)) {
map.put(slope, pointmap.get(points[j]));
} else
map.put(slope, map.get(slope) + 1);
}
}
for (Double key : map.keySet()) {
if (map.get(key) > max) {
max = map.get(key);
}
}
return max;
} else if (points.length != 0) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Point point1 = new Point(0,0);
Point point2 = new Point(0,0);
//Point point3 = new Point(2,2);
MaxPointsINLine maxpoint = new MaxPointsINLine();
Point[] points = { point1, point2};
System.out.println(maxpoint.maxPoints(points));
}
}
class Point {
int x;
int y;
Point() {
x = 0;
y = 0;
}
Point(int a, int b) {
x = a;
y = b;
}
@Override
public boolean equals(Object obj) {
Point that = (Point)obj;
if (that.x == this.x && that.y == this.y)
return true;
else
return false;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return 1;
}
}
公共类MaxPointsINLine{
int max=0;
int相同;
公共整数最大点(点[]点){
int max=0;
Map Map=newhashmap();
Map pointmap=newhashmap();
用于(点:点)
{
如果(!pointmap.containsKey(点))
{
pointmap.put(点,1);
}
其他的
{
pointmap.put(point,pointmap.get(point)+1);
}
}
如果(点长度>=2){
对于(int i=0;i最大值){
max=map.get(键);
}
}
返回最大值;
}else if(points.length!=0){
返回1;
}否则{
返回0;
}
}
公共静态void main(字符串[]args){
点1=新点(0,0);
点2=新点(0,0);
//点3=新点(2,2);
MaxPointsINLine maxpoint=新的MaxPointsINLine();
点[]点={point1,point2};
System.out.println(maxpoint.maxPoints(points));
}
}
类点{
int x;
int-y;
点(){
x=0;
y=0;
}
点(点a,点b){
x=a;
y=b;
}
@凌驾
公共布尔等于(对象obj){
点即=(点)obj;
如果(that.x==this.x&&that.y==this.y)
返回true;
其他的
返回false;
}
@凌驾
公共int hashCode(){
//TODO自动生成的方法存根
返回1;
}
}
总体策略似乎无法奏效。假设我们已经成功地用键值对(a,N)
填充了map
,其中a
是一个角度,N
是由角度a
连接的点对的数量。考虑以下6点安排:
**
**
**
明确地说,在(0,0)、(1,0)、(2,1)、(3,1)、(0,2)和(1,2)处存在点。您可以检查任何直线上的最大点数是否为2。但是,有3对点以相同角度连接:((0,0)、(1,0))、((2,1)、(3,1))和((0,2)、(1,2))。因此,map
将包含一个具有N=3
的键值对,但这不是原始问题的答案
由于上述安排,仅计算坡度是不够的。一个成功的算法必须以这样的方式来表示线,这样就可以区分平行线。 这里最直接的解决方法似乎是:一个可以考虑每一对点。对于每一对,计算另一点到连接两个点的线的距离。如果该距离接近零,则该点位于直线上 对所有线对执行此操作后,可以选择连接线上点数最多的线对 当然,这不是很优雅,因为它在O(n^3)中,并且执行两次计算。但它非常简单,而且相当可靠。我只是在这里实现了这一点: 用鼠标左键可以设置点。右键单击清除屏幕。将显示一行中的最大点数,并高亮显示相应的点 (编辑:根据注释更新为处理距离为0的点)
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.awt.geom.Line2D;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
公共类点直线测试
{
公共静态void main(字符串[]args)
{
SwingUtilities.invokeLater(新的Runnable()
{
@凌驾
公开募捐
{
createAndShowGUI();
}
});
}
私有静态void createAndShowGUI()
{
JFrame f=新的JFrame();
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f、 getContentPane().setLayout(新的BorderLayout());
f、 getContentPane().add(新的PointsPanel());
f、 设置大小(600600);
f、 setLocationRelativeTo(空);
f、 setVisible(真);
}
}
直线上的类点
{
//大ε,便于放置
//用鼠标在一条线上的一些点。。。
私有静态最终双ε=5.0;
List maxPointsOnLine=new ArrayList();
空隙计算
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PointsOnStraightLineTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(new PointsPanel());
f.setSize(600, 600);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class PointsOnStraightLine
{
// Large epsilon to make it easier to place
// some points on one line with the mouse...
private static final double EPSILON = 5.0;
List<Point> maxPointsOnLine = new ArrayList<Point>();
void compute(List<Point> points)
{
maxPointsOnLine = new ArrayList<Point>();
for (int i=0; i<points.size(); i++)
{
for (int j=i+1; j<points.size(); j++)
{
Point p0 = points.get(i);
Point p1 = points.get(j);
List<Point> resultPoints = null;
if (p0.distanceSq(p1) < EPSILON)
{
resultPoints = computePointsNearby(p0, points);
}
else
{
resultPoints = computePointsOnLine(p0, p1, points);
}
if (resultPoints.size() > maxPointsOnLine.size())
{
maxPointsOnLine = resultPoints;
}
}
}
}
private List<Point> computePointsOnLine(
Point p0, Point p1, List<Point> points)
{
List<Point> result = new ArrayList<Point>();
for (int k=0; k<points.size(); k++)
{
Point p = points.get(k);
double d = Line2D.ptLineDistSq(p0.x, p0.y, p1.x, p1.y, p.x, p.y);
if (d < EPSILON)
{
result.add(p);
}
}
return result;
}
private List<Point> computePointsNearby(
Point p0, List<Point> points)
{
List<Point> result = new ArrayList<Point>();
for (int k=0; k<points.size(); k++)
{
Point p = points.get(k);
double d = p.distanceSq(p0);
if (d < EPSILON)
{
result.add(p);
}
}
return result;
}
}
class PointsPanel extends JPanel implements MouseListener
{
private final List<Point> points;
private final PointsOnStraightLine pointsOnStraightLine;
PointsPanel()
{
addMouseListener(this);
points = new ArrayList<Point>();
pointsOnStraightLine = new PointsOnStraightLine();
}
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setColor(Color.BLACK);
for (Point p : points)
{
g.fillOval(p.x-2, p.y-2, 4, 4);
}
pointsOnStraightLine.compute(points);
int n = pointsOnStraightLine.maxPointsOnLine.size();
g.drawString("maxPoints: "+n, 10, 20);
g.setColor(Color.RED);
for (Point p : pointsOnStraightLine.maxPointsOnLine)
{
g.drawOval(p.x-3, p.y-3, 6, 6);
}
}
@Override
public void mouseClicked(MouseEvent e)
{
if (SwingUtilities.isRightMouseButton(e))
{
points.clear();
}
else
{
points.add(e.getPoint());
}
repaint();
}
@Override
public void mousePressed(MouseEvent e)
{
}
@Override
public void mouseReleased(MouseEvent e)
{
}
@Override
public void mouseEntered(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e)
{
}
}
/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
public int maxPoints(Point[] points) {
int result = 0;
for(int i = 0; i<points.length; i++){
Map<Double, Integer> line = new HashMap<Double, Integer>();
Point a = points[i];
int same = 1;
//System.out.println(a);
for(int j = i+1; j<points.length; j++){
Point b = points[j];
//System.out.println(" point " + b.toString());
if(a.x == b.x && a.y == b.y){
same++;
} else {
double dy = b.y - a.y;
double dx = b.x - a.x;
Double slope;
if(dy == 0){ // horizontal
slope = 0.0;
} else if(dx == 0){//eartical
slope = Math.PI/2;
} else {
slope = Math.atan(dy/dx);
}
Integer slopeVal = line.get(slope);
//System.out.println(" slope " + slope + " slope value " + slopeVal);
if(slopeVal == null){
slopeVal = 1;
} else {
slopeVal += 1;
}
line.put(slope, slopeVal);
}
}
for (Double key : line.keySet()) {
Integer val = line.get(key);
result = Math.max(result, val + same);
}
// for all points are same
result = Math.max(result, same);
}
return result;
}
}