149. 直线上最多的点数

149. 直线上最多的点数

class MaxPoints:
    """
    149. 直线上最多的点数
    https://leetcode.cn/problems/max-points-on-a-line/description/?envType=study-plan-v2&envId=top-interview-150
    """
    def solution(self, points: List[List[int]]) -> int:
        """
        时间复杂度 O(n^2 * log n)
        空间复杂度 O(log n)
        :param points: 
        :return: 
        """
        n = len(points)
        if n <= 2:
            return n

        ans = 0
        for i in range(n):
            if ans >= n - i or ans > n // 2:
                break

            hm = dict()
            for j in range(i + 1, n):
                x = points[i][0] - points[j][0]
                y = points[i][1] - points[j][1]

                if x == 0:
                    y = 1
                elif y == 0:
                    x = 1
                else:
                    if y < 0:
                        x = -x
                        y = -y

                    gcd_xy = self.gcd(abs(x), abs(y))
                    x /= gcd_xy
                    y /= gcd_xy

                # 将x缩放20001倍,可以理解为原本相邻x1,x2的距离由 1 放大至 20001,这样 无论y取任何[0, 2×10^4]中的值,
                # 都可以映射到这个间隔内,保证了任意两组数(x1,y1)和 (x2,y2),只要有一个值(x1 != x2 或 y1 != y2)不同,
                # 那映射后的val1 和 val2 也不同
                val = y + x * 20001
                hm[val] = hm.get(val, 0) + 1

            max_n = 0
            for k, v in hm.items():
                max_n = max(max_n, v + 1)

            ans = max(ans, max_n)

        return ans

    def gcd(self, a, b):
        """
        求a和b的最大公约数,时间复杂度 log n
        :param a:
        :param b:
        :return:
        """
        if b == 0:
            return a
        return self.gcd(b, a % b)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NLP_wendi

谢谢您的支持。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值