【Leetcode】149. Max Points on a Line 149. 直线上最多的点数

【Leetcode】149. Max Points on a Line 149. 直线上最多的点数_第1张图片

解法

太多坑了这题
只能依次记录每条直线上的点
需要解决的问题就是:

如何唯一地标识一条直线?

用三元组(A,B,C),要注意2点,一是最简约分,二是统一正负号。比如我就统一为第一个非0的数为正

另外还有一个坑:

如何处理重复点?

首先,重复点不能作为得到直线的两个端点
其次,重复点的重复次数也是答案的候选者之一

# 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
        """
        def simplify(a,b,c):
            # print 'before:',a,b,c
            d = 2
            m = min(map(abs,filter(lambda x:x,(a,b,c))) or [-1])
            if m==-1:
                return a,b,c
            while d*d<=m:
                if m%d==0:
                    while a%d==0 and b%d==0 and c%d==0:
                        a,b,c = a/d,b/d,c/d
                        m /= d
                    while m%d==0:
                        m/=d
                d += 1
            if m>1:
                while a%m==0 and b%m==0 and c%m==0:
                        a,b,c = a/m,b/m,c/m
            # print 'after',a,b,c
            return a,b,c
            
        def ABC(a,b):
            x = b[0]-a[0]
            y = b[1]-a[1]
            i,j,k = y,-x,a[1]*x-y*a[0]
            if i<0 or (i==0 and j<0) or (i==0 and j==0 and k<0):
                i,j,k = -i,-j,-k
            return i,j,k
        from collections import defaultdict
        cnt = defaultdict(set)
        for i,p in enumerate(points):
            cnt[(p.x,p.y)].add(i)
        n = len(cnt)
        if n<=2:
            return len(points)
        ans = defaultdict(set)
        for i,j in itertools.combinations(cnt.keys(),2):
            line = simplify(*ABC(i,j))
            ans[line] |= cnt[i] | cnt[j]
        return max(map(len,ans.values()+cnt.values()))

你可能感兴趣的:(Leetcode)