Max Points on a Line

来源:互联网 发布:免费wifi广告软件 编辑:程序博客网 时间:2024/05/21 02:36

题目描述:

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

给n个点,看最多多少个点在同一条线。

我真的服了自己,一开始想那么麻烦,还去求y=kx+b。最后还有问题,因为当k失去精度后,b的计算可能不相等。

下面是一段非常复杂的计算,还没有成功,就当复习了hashcode和equals用法!

这里将所有的直线全部计算出来,包括水平线,竖直线,以及各种不同的k,b组成的线。太麻烦了!!!

这个题还有一点就是所给的点可能有重复的,这个地方要处理好。

class Point {int x;int y;Point() { x = 0; y = 0; }Point(int a, int b) {x = a; y = b; }}class Line{    double k;    double b;    Line(){        k = 0; b = 0;     }    Line(double k, double b) {        this.k = k; this.b = b;     }    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        long temp;        temp = Double.doubleToLongBits(b);        result = prime * result + (int) (temp ^ (temp >>> 32));        temp = Double.doubleToLongBits(k);        result = prime * result + (int) (temp ^ (temp >>> 32));        return result;    }        @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Line other = (Line) obj;        if (Double.doubleToLongBits(b) != Double.doubleToLongBits(other.b))            return false;        if (Double.doubleToLongBits(k) != Double.doubleToLongBits(other.k))            return false;        return true;    }}public class Solution149 {    public int maxPoints(Point[] points) {        if(points.length==1||points.length==2)            return points.length;        int kind=1,sum=1;        for(int i=1;i<points.length;i++){            if(points[i].x==points[0].x&&points[i].y==points[0].y)                sum++;            else{                kind++;                break;            }        }        if(kind==1)            return sum;        int maxpoint=0,n=points.length;        Map<Integer, Integer> horizenMap=new HashMap<Integer, Integer>();        Map<Integer, Integer> verticalMap=new HashMap<Integer, Integer>();        Map<Line, Integer> lineMap=new HashMap<Line, Integer>();        for(int i=0;i<n;i++){            boolean horizenflag=true;            boolean verticalflag=true;            Set<Double> kSet=new HashSet<Double>();            for(int j=0;j<n;j++){                if(i==j||(points[i].y==points[j].y&&points[i].x==points[j].x))                    continue;                if(points[i].x==points[j].x&&points[i].y!=points[j].y){                    if(verticalflag){                        if(!verticalMap.containsKey(points[i].x))                            verticalMap.put(points[i].x,1);                        else                            verticalMap.put(points[i].x,verticalMap.get(points[i].x)+1);                        verticalflag=false;                    }                }                else if(points[i].y==points[j].y&&points[i].x!=points[j].x){                    if(horizenflag){                        if(!horizenMap.containsKey(points[i].y))                            horizenMap.put(points[i].y,1);                        else                            horizenMap.put(points[i].y,horizenMap.get(points[i].y)+1);                        horizenflag=false;                    }                }else{                    double k=1.0 * (points[i].y - points[j].y) / (points[i].x - points[j].x);                    double b=points[j].y-k*points[j].x;                    if(!kSet.contains(k)){                        Line line=new Line(k, b);                        if(!lineMap.containsKey(line))                            lineMap.put(line, 1);                        else                            lineMap.put(line, lineMap.get(line)+1);                        kSet.add(k);                    }                }            }        }        for(Integer key:horizenMap.keySet())            maxpoint=horizenMap.get(key)>maxpoint?horizenMap.get(key):maxpoint;             for(Integer key:verticalMap.keySet())            maxpoint=verticalMap.get(key)>maxpoint?verticalMap.get(key):maxpoint;         for(Line key:lineMap.keySet())            maxpoint=lineMap.get(key)>maxpoint?lineMap.get(key):maxpoint;    return maxpoint;    }}
后来想起来每次经过一个点,就将这个点能够经过的所有直线所包含最多的点算出来就行了!!

写了下面一段代码,AC了,思路清晰就能节约很长时间,所以一定要想清楚再动手才能提高效率!


public class Solution {    public int maxPoints(Point[] points) {        if(points.length<3)            return points.length;        int maxpoint=0,n=points.length;        int result=0;        Map<Double, Integer> lineMap=new HashMap<Double, Integer>();        for(int i=0;i<n;i++){            maxpoint=0;lineMap.clear();            int horizenNum=0,verticalNum=0;            int dumplicate=0;            for(int j=0;j<n;j++){                if(i==j||(points[i].y==points[j].y&&points[i].x==points[j].x))                    dumplicate++;                else if(points[i].x==points[j].x&&points[i].y!=points[j].y)                    verticalNum++;                else if(points[i].y==points[j].y&&points[i].x!=points[j].x)                    horizenNum++;                else{                    double k=1.0 * (points[i].y - points[j].y) / (points[i].x - points[j].x);                    if(!lineMap.containsKey(k))                        lineMap.put(k,1);                    else                        lineMap.put(k,lineMap.get(k)+1);                }            }            horizenNum+=dumplicate;            verticalNum+=dumplicate;            maxpoint=horizenNum>verticalNum?horizenNum:verticalNum;             for(Double key:lineMap.keySet())                 maxpoint=lineMap.get(key)+dumplicate>maxpoint?lineMap.get(key)+dumplicate:maxpoint;            result=maxpoint>result?maxpoint:result;        }        return result;    }}


0 0