力扣python149. 直线上最多的点数
Posted _less is more
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣python149. 直线上最多的点数相关的知识,希望对你有一定的参考价值。
写法一
自己的解,需要注意的点是:
(1)使用k和b来作为唯一标识
(2)当直线为垂直时,b为None,斜率k需要加入x轴位置来作为唯一标识
class Solution:
def maxPoints(self, points) -> int:
pointsNum = len(points)
de = defaultdict(list)
for i in range(pointsNum):
for j in range(i+1, pointsNum):
deltaX = points[i][0] - points[j][0]
k = (points[i][1] - points[j][1])/deltaX if deltaX != 0 else f"{float('inf')}{points[j][0]}"
b = points[i][1] - k*points[i][0] if type(k) != str else None
if str(points[i]) not in de[(k, b)]:
de[(k, b)].append(str(points[i]))
if str(points[j]) not in de[(k, b)]:
de[(k, b)].append(str(points[j]))
max_ = 1
for per in de:
max_ = max(len(de[per]), max_)
return max_
写法二
官方方法,利用了一定的剪枝
class Solution:
def gcd(self, a, b):
return self.gcd(b, a % b) if b else a # 直到b为0就返回a,即最大公约数
def maxPoints(self, points) -> int:
n = len(points)
if n <= 2: # 当点少于等于2(剪枝一)
return n # 直接返回,必定同一直线
ret = 0 # 记录最大可能的在同一直线的点数
for i in range(n):
# 当之前的最多点都已经大于剩下的点,或过半了,则不用再查了(剪枝三,剪枝四)
if ret >= n - i or ret > n / 2:
break
mp = defaultdict(int) # 只需要保存i及之后的点的斜率,从而避免斜率同b不同的情况(剪枝二)
for j in range(i + 1, n):
x, y = points[i][0] - points[j][0], points[i][1] - points[j][1]
if x == 0:
y = 1
elif y == 0:
x = 1
else:
x, y = (-x, -y) if y < 0 else (x, y)
gcdXY = self.gcd(abs(x), abs(y))
x /= gcdXY
y /= gcdXY
mp[y + x * 20001] += 1 # 保证每个斜率k映射到的值不同, 比如1/2 和 2/1, 直接加起来都是3
ret = max(ret, max([mp[per] + 1 for per in mp]))
return ret
以上是关于力扣python149. 直线上最多的点数的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode第149题—直线上最多的点数—Python实现