题号:面试题16.14 最佳直线
题目内容:
给定一个二维平面及平面上的 N 个点列表Points,其中第i个点的坐标为Points[i]=[Xi,Yi]。请找出一条直线,其通过的点的数目最多。
设穿过最多点的直线所穿过的全部点编号从小到大排序的列表为S,你仅需返回[S[0],S[1]]作为答案,若有多条直线穿过了相同数量的点,则选择S[0]值较小的直线返回,S[0]相同则选择S[1]值较小的直线返回。
注:
2 <= len(Points) <= 300len(Points[i]) = 2
示例:
输入: [[0,0],[1,1],[1,0],[2,0]] 输出: [0,2] 解释: 所求直线穿过的3个点的编号为[0,2,3]
解题过程与思路(本题采用暴力循环方式和优化方式):
题目要求一条穿过最多点的直线,对于给定起始点,可以利用剩余点与起始点连成的直线的斜率是否相等来进行判断,因为给定一点和斜率能唯一确定一条直线(点斜式)。
具体实现过程:可以从给定点集的第一点开始(一层循环),遍历剩余的点(两层循环),先确定一条直线,再循环遍历所有点(三层循环),如果斜率相等,则加入结果集。遍历结束后,判断本次与上次结果集的长度,编号,决定保留还是丢弃。
使用python编写代码如下:
def best_line(points: List[List[int]]) -> List[int]:
s = []
for i in range(len(points) - 1): # 只需要遍历到倒数第二个点即可
for j in range(i + 1, len(points)): # 选取剩下还没有当过起始点的点
temp = []
delta_x = points[j][0] - points[i][0] # 计算横坐标差
if delta_x == 0: # 考虑斜率不存在的情况
for index in range(len(points)):
if points[index][0] == points[i][0]: # 横坐标相同,加入到列表中
temp.append(index)
else:
temp.append(i) # 添加起始点
k = (points[j][1] - points[i][1]) / delta_x # 计算斜率
for index in range(len(points)):
if points[index][0] == points[i][0]: # 斜率不存在,跳过
continue
if k == (points[index][1] - points[i][1]) / (points[index][0] - points[i][0]): # 斜率相同,加入到列表中
temp.append(index)
temp.sort() # 升序排序,便于比较编号
if len(temp) > len(s): # 对比列表长度
s = temp
if len(temp) == len(s): # 对比编号
if temp[0] < s[0] or (temp[0] == s[0] and temp[1] < s[1]):
s = temp
return [s[0], s[1]]
可以看到上述代码使用了三层循环,运行效率极慢,并且需要处理复杂的边界条件,显然不够优雅,让我们从头开始优化思路,具体优化过程:力扣算法题:最佳直线(优化)。
关注我,从零开始的算法小白之路。
&spm=1001.2101.3001.5002&articleId=162374255&d=1&t=3&u=27e4f02a8611414ca8d8074eaa0d00db)
2732

被折叠的 条评论
为什么被折叠?



