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;
    }
}

歡迎關注微信公衆號

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