直线上最多的点数(枚举直线(w,b))

本题的最简单的方法暴力解三层循环

题目链接:直线上最多的点数Hard
那么复杂度就是 O ( n 3 ) O(n^3) O(n3),按照题目中的点数范围,最大我们需要计算 1 0 6 10^6 106的量级。

哈希表 + 两次遍历

下面给出该方法的计算过程:

  • 首先枚举两点之间确定的直线斜率和截距,并通过转化为字符串进行保存,作为key放入到字典中,经过两层循环我,那我我们便可以得到每一条直线下共有多少对点,满足这条直线的斜率和截距,复杂度 O ( n 2 ) O(n^2) O(n2)
  • 之后我们便可以通过一次遍历的方法得到字典中那一条直线所含的点对最多。便可以通过解方程得到。
  • 如何计算:
    在这里插入图片描述

比如说一共有三个点存在一条直线上,那么我们通过两层遍历便可以得到一共有 n ( n − 1 ) / 2 = 3 ∗ 2 / 2 = 3 n(n-1)/2 = 3*2/2 = 3 n(n1)/2=32/2=3的点对。有这个方程之后假设最大的点对为 x x x。那么有下面的方法求解n:
n ( n − 1 ) / 2 = x n 2 − n + 1 4 = 2 x + 1 4 ( n − 1 2 ) 2 = 2 x + 1 4 n = 2 x + 1 4 + 1 2 n(n-1)/2 = x \\ n^2 - n + \frac{1}{4} = 2x + \frac{1}{4} \\ (n - \frac{1}{2})^2 = 2x + \frac{1}{4} \\ n = \sqrt{2x + \frac{1}{4}} + \frac{1}{2} n(n1)/2=xn2n+41=2x+41(n21)2=2x+41n=2x+41 +21

  • 关于截距和斜率的保存方式:
    由于 w = d y d x , 而 1 ≤ ∣ d y ∣ , ∣ d x ∣ ≤ 1 0 4 w = \frac{d_y}{d_x}, \text{而}1 \le |d_y|, |d_x| \le 10^4 w=dxdy,1dy,dx104,所以 w w w的最小间隔为 0.00005 0.00005 0.00005,所以我们在转化为 str \text{str} str的时候只包含小数点的前5位便可以,保留过多和过少分别会导致同一条直线分为多条直线,以及多条直线成为一条直线。

代码:

class Solution:
    def maxPoints(self, points: List[List[int]]) -> int:
        rate = collections.defaultdict(int)
        for i in range(len(points)):
            for j in range(i+1, len(points)):
                if points[i][0] == points[j][0]: #竖线
                    rate["inf" + "<>" + str(points[i][0])] += 1
                elif points[i][1] == points[j][1]:  #横线
                     rate["0<>" + str(points[i][1])] += 1
                else: #普通线
                    d_x = points[i][0] - points[j][0]
                    d_y = points[i][1] - points[j][1]
                    w =  d_y / d_x
                    b = points[i][1] - w * points[i][0]
                    rate[f'{w:.5f}' + "<>" + f"{b:.5f}"] += 1
        max_cnt = 0
        for key in rate.keys():
            if rate[key] > max_cnt:
                max_cnt = max(max_cnt, rate[key])
        return int(sqrt(2 * max_cnt + 0.25) + 0.5)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值