摘要:分子分母同時除以他們的最大公約數即可得到最簡分數,一般求的是兩個正整數的。這道題和有可能是,分別表示與軸或軸平行的斜率注意不能同時為表示同一個點沒有意義,所以這道題我們規定取值范圍。
Max Points on a Line
哈希表法 復雜度Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
O(N^2) 時間 O(N) 空間, N為點數
思路應知應會:
平面里確定一條直線要兩個數據,可以是兩個不同的點(高中數學做法),也可以是一個點加一個斜率(這道題做法)
斜率k = (y2 - y1)/(x2 - x1),當 x1 == x2 時,分母為0,斜率為無窮,表示和y軸平行的直線們
在計算機里使用double表示斜率,是不嚴謹的也是不正確的,double有精度誤差,double是有限的,斜率是無限的,無法使用有限的double表示無限的斜率,不過此題的test case沒有涉及這個問題
表示斜率最靠譜的方式是用最簡分數,即分子分母都無法再約分了。分子分母同時除以他們的最大公約數gcd即可得到最簡分數
gcd(a,b),一般求的是兩個正整數的gcd。這道題a和b有可能是0,分別表示與x軸或y軸平行的斜率(注意ab不能同時為0,表示同一個點沒有意義),所以這道題我們規定ab取值范圍:a>=0,b>=0。至于負數,先變成正數取gcd,再確定最終斜率的正負
gcd ( a , b ) = (b == 0) ? a : gcd ( b , a % b ), a,b是任意非負整數且a,b至少有一個不為0
觀察gcd(a,b),假設a,b為非負整數:
a和b中有一個為零,那么gcd為另一個不為0的數;
a和b都為0,gcd為0;
算法:
沒什么算法就是窮舉:
對每個點,都計算一下該點和其他點連線的斜率,這樣對于這個點來說,相同斜率的直線有多少條,就意味著有多少個點在同一條直線上,因為這些直線是相同的。另外,如果計算過點A和點B的直線,當算到點B時,就不用再和A連線了,因為AB這條直線上的點數已經都計算過了。這里,我們用哈希表,以斜率為key,記錄有多少重復直線。
求gcd的utility:
public int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); }
兩層循環外層 i 從 0 到 n, 內層 j 從 i+1 到 n
如果想要自定義Slope(斜率)類作為HashMap的Key的話要重寫hashCode()和equals()函數, 偷懶的話可以把斜率的分數表示成String作為Key,這樣就省了一些事
hashmap的value的含義應定義為:過cur點以key為斜率的直線有幾個除了cur以外的點。在算完 過cur的所有直線后,統計cur點的總個數howManyCur,加到當前點最多的直線上,即可得到含cur點的最大直線上的點數
代碼/** * Definition for a point. * class Point { * int x; * int y; * Point() { x = 0; y = 0; } * Point(int a, int b) { x = a; y = b; } * } */ public class Solution { public int maxPoints(Point[] points) { if (points.length <= 1) return points.length; int maxUniv = Integer.MIN_VALUE; for (int i = 0; i < points.length; i++) { Point cur = points[i]; HashMapmap = new HashMap (); int howManyCur = 1, maxLocal = 0; for (int j = i + 1; j < points.length; j++) { //這里可以從i+1開始,之前的都算過了 Point iter = points[j]; if (iter.x == cur.x && iter.y == cur.y) {//同一頂點 howManyCur += 1; } else { //不同頂點 String key = getSlopeInString(cur, iter); //map里存(過cur點,斜率key)代表的直線有多少除了cur的點 map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1); maxLocal = Math.max(maxLocal, map.get(key)); } } maxLocal = howManyCur + maxLocal; maxUniv = Math.max(maxLocal, maxUniv); } return maxUniv; } public String getSlopeInString(Point cur, Point iter) { int numerator = iter.y - cur.y; int denominator = iter.x - cur.x; String sign = getSign(numerator, denominator); int gcd = gcd(Math.abs(numerator), Math.abs(denominator));//0和任意一個非零數"a"的gcd為"a",0和0的gcd為0,所以斜率為無窮的情況分母為0 return sign + Math.abs(numerator)/gcd + "/" + Math.abs(denominator)/gcd; } //a和b為非負整數 且 a和b不同時為0 public int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } public String getSign(int a, int b) { if (a <= 0 && b <= 0 || a >= 0 && b >= 0) return "+"; else return "-"; } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64800.html
摘要:哈希表復雜度時間空間思路一個點加一個斜率,就可以唯一的確定一條直線。這里,我們用哈希表,以斜率為,記錄有多少重復直線。注意哈希表的為,但是可以有正和負的,而且不一樣。 Max Points on a Line Given n points on a 2D plane, find the maximum number of points that lie on the same stra...
摘要:這個題的思路就是找數組里的兩個點,用這兩個點來做一條直線,然后看數組里的點都在直線上不,我用的是兩點式,需要考慮兩個點或坐標相同的特殊情況。 Max Points on a Line https://oj.leetcode.com/problems/max-points-on-a-line/ Given n points on a 2D plane, find the maximu...
摘要:題目解法這道題主要是判斷個點是否沿某條線對稱,可以從提示看出來所有的點應該要滿足所以先把所有的點掃一遍存下來,找到和然后再掃一遍,判定是否點都是延直線對稱的。時間復雜度空間復雜度代碼 題目: Given n points on a 2D plane, find if there is such a line parallel to y-axis that reflect the gi...
Given n points on a 2D plane,find the maximum number of points that lie on the same straight line. from decimal import Decimal # Definition for a point. class Point: def __init__(self, a=0, b=0)...
閱讀 1478·2021-10-14 09:43
閱讀 1442·2021-10-09 09:58
閱讀 1937·2021-09-28 09:42
閱讀 3728·2021-09-26 09:55
閱讀 1752·2021-08-27 16:23
閱讀 2756·2021-08-23 09:46
閱讀 906·2019-08-30 15:55
閱讀 1405·2019-08-30 15:54