1. 程式人生 > >【LeetCode】149. Max Points on a Line 解題報告(Python)

【LeetCode】149. Max Points on a Line 解題報告(Python)

作者: 負雪明燭
id: fuxuemingzhu
個人部落格: http://fuxuemingzhu.cn/


目錄

題目地址:https://leetcode.com/problems/max-points-on-a-line/description/

題目描述

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

Example 1:

Input: [[1,1],[2,2],[3,3]]
Output: 3
Explanation:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4

Example 2:

Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
Output: 4
Explanation:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6

題目大意

判斷最多有多少個點在同一直線上。

解題方法

字典+最大公約數

這個題是個Hard題,而且通過率非常低。其實做法一點都不難。

我們想想如何判斷三個點是否在一個直線上?初中知識告訴我們,兩點確定一個直線。如果已經確定一個點,那麼只需要計算另外兩個點和當前點的斜率是否相等即可。當然如果另外兩個點當中如果有和當前點重合的就不能直接求斜率了,這種情況重合的兩個點無論怎麼樣都會和第三個點共線的。

在計算斜率的時候需要用到技巧,因為如果兩個點的橫座標重合了,那麼斜率是無窮大;如果斜率是浮點數,還會涉及到浮點數精度問題。所以使用了最大公約數這個技巧。我們不要直接計算斜率,而是相當於最簡分式的形式,使用pair或者Python中的tuple,儲存已經化為最簡分數的兩個數值,然後使用字典來統計這個pair出現了多少次。

最後的結果是共線並且不重合的點的最大個數+重疊的點的個數。

時間複雜度是O(N^2),空間複雜度是O(N)。

# Definition for a point.
# class Point(object):
#     def __init__(self, a=0, b=0):
#         self.x = a
#         self.y = b

class Solution(object):
    def maxPoints(self, points):
        """
        :type points: List[Point]
        :rtype: int
        """
        N = len(points)
        res = 0
        for i in range(N):
            lines = collections.defaultdict(int)
            duplicates = 1
            for j in range(i + 1, N):
                if points[i].x == points[j].x and points[i].y == points[j].y:
                    duplicates += 1
                    continue
                dx = points[i].x - points[j].x
                dy = points[i].y - points[j].y
                delta = self.gcd(dx, dy)
                lines[(dx / delta, dy / delta)] += 1
            res = max(res, (max(lines.values()) if lines else 0) + duplicates)
        return res
                
    def gcd(self, x, y):
        return x if y == 0 else self.gcd(y, x % y)

日期

2018 年 11 月 10 日 —— 這麼快就到雙十一了??