返回

洞悉 LeetCode 149:从简单几何角度直击要点

后端

直线上的最大点数量问题概述

直线上的最多点数问题是算法领域的经典题目之一。给定一个二维平面上的若干个点,目标是计算出通过这些点中任意两点所形成的直线的最大点数。这一挑战在于如何有效地找出所有可能的直线,并确定每条直线上包含的最多的点。

解析几何学中的核心

解决此问题的关键在于理解解析几何的基础概念:斜率和截距。一条直线可以通过其斜率(slope)和与y轴交点的截距来定义。因此,如果多个点位于同一直线,则这些点形成的任意两条连线应具有相同的斜率。

理解斜率

对于任意两点(x1, y1)和(x2, y2),它们之间的斜率计算公式为:

[ slope = \frac{y_2 - y_1}{x_2 - x_1} ]

当直线垂直于x轴时,分母(x_2 - x_1)将变为0,此时定义该斜率为无穷大。

问题解决方案

使用哈希表计算最大点数

通过哈希表记录每个斜率出现的次数,可以高效地找出经过最多点数的直线。这种方法的关键在于对每一对点进行两两比较,确定它们之间的斜率,并在哈希表中维护这个计数。

Python代码实现

def maxPoints(points):
    if len(points) <= 2:
        return len(points)
    
    from collections import defaultdict
    
    def gcd(a, b): 
        while b: 
            a, b = b, a % b 
        return a
    
    result = 0
    for i in range(len(points)):
        slope_map = defaultdict(int)
        duplicates = 1
        
        for j in range(i + 1, len(points)):
            dx, dy = points[j][0] - points[i][0], points[j][1] - points[i][1]
            
            if (dx == 0) and (dy == 0):
                duplicates += 1
                continue
            
            g = gcd(dx, dy)
            slope = (dx // g, dy // g)

            slope_map[slope] += 1
        
        result = max(result, max(slope_map.values(), default=0) + duplicates)
    
    return result

操作步骤

  1. 对于给定的点集,首先检查其长度是否小于等于2,若如此,则直接返回该长度。
  2. 使用一个哈希表slope_map来记录斜率及其出现次数。对于每一对不同的点,计算它们之间的斜率并更新计数。
  3. 需要处理的是那些坐标完全相同的点,这类点会增加直线上的点数而不改变其斜率。
  4. 最后,通过比较哈希表中的最大值来确定最多点数的直线。

安全建议

  • 在实现过程中,注意避免除以0的情况,这可以通过判断分母是否为零并单独处理来解决。
  • 使用GCD(最大公约数)函数简化斜率表示,确保斜率表达式唯一且能准确地进行比较。

此方法在时间和空间复杂度上均表现良好。通过巧妙利用哈希表和几何原理,可以高效找到直线上最多的点数,这一问题的解答不仅展示了算法的魅力,也揭示了几何学中的深层关联。

相关资源