穷举法:max-points-on-a-line

来源:互联网 发布:linux怎么重启服务器 编辑:程序博客网 时间:2024/06/06 01:45

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
析:此处的在一条直线上也包含斜的直线,因此分为水平竖直线、斜线两种情况。
如果是水平竖直线,直接以横坐标或纵坐标为参考作统计即可;
如果是斜线,得先把斜线定义成Line类,包含k b两个值,
之后分别统计每条斜线上的点的个数。
斜线那个方法的复杂度为o(n*n),因为创建斜线时需要双层循环。
自定义的类加上equals和hashCode方法

import java.util.*;public class Main {    public static void main(String[] args){        Scanner sc= new Scanner(System.in);        Main main = new Main();        Point[] points =new Point[4];        points[0]= new Point(3,10);        points[1]= new Point(0,2);        points[2]= new Point(0,2);        points[3]= new Point(3,10);        System.out.println(main.maxPoints(points));    }    public int maxPoints(Point[] points) {        if(points==null || points.length==0)            return 0;        if(points.length==1)            return 1;        return Math.max(maxPoints1(points),maxPoints2(points));    }    // 考虑在水平线或竖直线    public int maxPoints1(Point[] points) {        // map为 <x或y的值,出现点的次数>        Map<Integer,Integer> mapx = new HashMap<>();        Map<Integer,Integer> mapy = new HashMap<>();        for(Point p:points){            if(!mapx.containsKey(p.x))                mapx.put(p.x,1);            else                mapx.put(p.x, mapx.get(p.x)+1);            if(!mapy.containsKey(p.y))                mapy.put(p.y,1);            else                mapy.put(p.y, mapy.get(p.y)+1);        }        int max=0;        for(Integer t:mapx.keySet()){            max = max>mapx.get(t)?max:mapx.get(t);        }        for(Integer t:mapy.keySet()){            max = max>mapy.get(t)?max:mapy.get(t);        }        return max;    }    // 考虑斜线    public int maxPoints2(Point[] points) {        Set<Line> lineSet = new HashSet<>();        // <直线,直线上点的个数>        Map<Line,Integer> map = new HashMap<>();        for(int i=0;i<points.length;i++)            for(int j=i+1;j<points.length;j++){            Point p1 = points[i];            Point p2 = points[j];            if(p1.x!=p2.x && p1.y!=p2.y){                double k=(p1.y-p2.y)*1.0/(p1.x-p2.x);                double b= p1.y-k*p1.x;                Line line = new Line(k,b);                lineSet.add(line);            }            }        for(Point p:points){                for(Line line:lineSet){                    // 如果点在直线上                    if (Math.abs(p.y-line.k*p.x-line.b)<1e-9){                        if(map.containsKey(line))                            map.put(line,map.get(line)+1);                        else                            map.put(line,1);                    }                }        }        int res=0;        for(Line l:map.keySet()){            res=res>map.get(l)?res:map.get(l);        }        return res;    }}class Point {    int x,y;    public Point(){    }    public Point(int x, int y) {        this.x = x;        this.y = y;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Point point = (Point) o;        if (x != point.x) return false;        return y == point.y;    }    @Override    public int hashCode() {        int result = x;        result = 31 * result + y;        return result;    }}class Line{    double k,b;    public Line(double k, double b) {        this.k = k;        this.b = b;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Line line = (Line) o;        if (Double.compare(line.k, k) != 0) return false;        return Double.compare(line.b, b) == 0;    }    @Override    public int hashCode() {        int result;        long temp;        temp = Double.doubleToLongBits(k);        result = (int) (temp ^ (temp >>> 32));        temp = Double.doubleToLongBits(b);        result = 31 * result + (int) (temp ^ (temp >>> 32));        return result;    }}
原创粉丝点击