1. 程式人生 > >【leetcode】149.(Hard)Max Points on a Line

【leetcode】149.(Hard)Max Points on a Line

解題思路:
兩個for迴圈
以題目給的例子為例:{{1,1},{3,2},{5,3},{4,1},{2,3},{1,4}}
假如三個點point1 point2 point3在同一條直線上,則它們的斜率比值是一樣的:

(point1.y-point2.y)/(point1.x-point2.x)=(point1.y-point3.y)/(point1.x-point3.x)

根據上面的式子可以計算出基於每個點的不同斜率上的點的個數。

例如對第一個點{1,1}來說,我們從第二個點開始計算dx和dy值,有:

dx,dy 直線上的點
2,1 {1,1},{3,2},{5,3}
0,1 {1,1},{4,1}
1,2 {1,1},{2,3}
1,0 {1,1},{1,4}

最多的點是斜率為dx=2 dy=1上的點,共3個。


對於第二個點,我們從第三個點開始計算不同dx和dy上的點的數量。因為在計算第一個點時,我們已經計算完了包含第一個點時所有的可能情況,所有沒必要重複計算,可得:

dx,dy 直線上的點
2,1 {3,2},{5,3}
1,-1 {3,2},{4,1},{2,3},{1,4}
1,2 {5,3},{4,1}
1,0 {5,3},{2,3}
4,-1 {5,3},{1,4}

最多的點是斜率為dx=1,dy=-1上的點,共4個。

對剩下的點進行同樣的計算可以得到總共n張表格,n是點的個數。

這裡我們的內迴圈就是一張表中每一行的內容,外迴圈就是所有的表


對於最大直線點數的更新用2個引數來維護。max表示以當前點為基點時最大的點數,例如以{1,1}為基點時最大點數是3({1,1}{3,2}{5,3}),在內迴圈內更新
res是我們的結果,在外迴圈內更新


時間複雜度:O(n^2)
空間複雜度:O(n)


提交程式碼:

class Solution{
    public int maxPoints(Point[] points) {
    	if(points.length<=2)	return points.length;
    	
    	int res=0,duplicate=0,max=0;
    	Map<Integer,Map<Integer,Integer>> map=new HashMap<>();	
    	
    	for(int i=0;i<points.length;i++) {
    		map.clear();duplicate=0;max=0;
    		for(int j=i+1;j<points.length;j++) {
    			int dx=points[i].x-points[j].x;
    			int dy=points[i].y-points[j].y;
    			
    			if(dx==0&&dy==0) {
    				duplicate++;
    				continue;
    			}
    			int gcd=getGCD(dx,dy);
    			if(gcd!=0) {
    				dx/=gcd;
    				dy/=gcd;
    			}
    			if(map.containsKey(dx)) {
    				if(map.get(dx).containsKey(dy)) {
    					map.get(dx).put(dy, map.get(dx).get(dy)+1);
    				}else {
    					map.get(dx).put(dy, 1);
    				}
    			}else {
    					Map<Integer,Integer> tmp=new HashMap<>();
    					tmp.put(dy, 1);
    					map.put(dx, tmp);
    				}
    			max=Math.max(map.get(dx).get(dy), max);
    			}
    		if(max+duplicate+1>res)	res=max+duplicate+1;
    	}
    			
    	return res;
    	}
    
    private int getGCD(int a,int b) {
    	if(b==0)	return a;
    	return getGCD(b,a%b);
    }
}

執行結果:
在這裡插入圖片描述