LeetCode.max-points-on-a-line

转载自微信公众号

题 目 :

对于给定的n个位于同一二维平面上的点,求最多能有多少个点位于同一直线上
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

分 析 :

分为n、n-1、n-2……3等组(每组分别包含n个点、n-1个点……),找到每组中包含第一个点的点数最多的直线(每个点与第一个点有一个斜率,通过斜率是否相等判断是否在同一条直线),则每组结果的最大值即为所求;

原 理 :

所求直线所包含的点,一定有一个最靠前的i点,使得直线上所有点为i~1的子集,所求值即为i组的结果

注 意 事 项 :

1、存在与第一个点相同的点;
2、使用浮点数不一定能准确的表示斜率,在此使用由String表示的分数来表示斜率

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
class Solution {
    public int maxPoints(Point[] points) {
        int result=0;
        if(points.length<3) return points.length;
        for(int i=0;i<points.length-1;i++){
            HashMap map=new HashMap();
            int maxNum=0,sameAsI=0;
            for(int j=i+1;j<points.length;j++){
                String key=xieLv(points[i],points[j]);
                if(points[i].x==points[j].x&&points[i].y==points[j].y) {
                    sameAsI++;
                    continue;
                }else {
                    map.put(key,map.containsKey(key) ? map.get(key)+1:1);
                }
                maxNum= Math.max(maxNum,map.get(key));
            }
            result=Math.max(result,maxNum+sameAsI);
        }
        return result+1;
    }

    private String xieLv(Point a,Point b){
        int x=a.x-b.x,y=a.y-b.y;
        if(x==0) return fuHao(x,y)+"ANY"+"/"+0;
        else if(y==0) return fuHao(x,y)+0+"/"+"ANY";
        int gcb=gcb(Math.abs(y),Math.abs(x));
        return fuHao(x,y)+Math.abs(y)/gcb+"/"+Math.abs(x)/gcb;
    }
    private String fuHao(int x,int y){
        if(x>=0&&y>=0||x<=0&&y<=0){
            return "+";
        }else return "-";
    }
    private int gcb(int a,int b){
        if(b==0) return a;
        else return gcb(b,a%b);
    }
}

当然还有一种最简单直接的思路:

  1. 选择第一个点A1
  2. 选择第二个点A2, 和第一个点构成一条直线,
  3. 遍历剩下的n-2个点Ai, 判断Ai与A1构成的直线是否与A2与A1构成的直线保持一致,若是,则A1A2直线上的点数就+1;
  4. 每次求完A1A2直线上的最大点数, 和结果取最大值. 遍历结束就是结果

判断是否在一条直线上时, 注意有特殊情况. 并且斜率相等判断用乘法, 别用除法!



public class Solution {
    public int maxPoints(Point[] points) {
        if (null == points) {
            return 0;
        } else if (points.length < 3) {
            return points.length;
        }
        int maxPoints = 2;
        for (int i = 0; i < points.length; i++) {
            int x1 = points[i].x;
            int y1 = points[i].y;
            for (int j = i + 1; j < points.length; j++) {
                int x2 = points[j].x;
                int y2 = points[j].y;
                int max = 2;
                for (int k = 0; k < points.length; k++) {
                    if (k == i || k == j) {
                        continue;
                    }
                    int x3 = points[k].x;
                    int y3 = points[k].y;
                    boolean flag;
                    if (x1 == x2) {
                        flag = x3 == x1;
                    } else if (y1 == y2) {
                        flag = y3 == y1;
                    } else {
                        flag = (y2 - y1) * (x3 - x1) == (y3 - y1) * (x2 -x1);
                    }
                    if (flag) {
                        max++;
                    }
                }
                maxPoints = Math.max(maxPoints, max);
            }
        }
        return maxPoints;
    }
}

欢迎关注微信公众号

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章