You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LeetCode 直线上最多点数问题:解法错误排查及哈希表必要性疑问

问题排查与修复方案

嘿,我仔细看了你的代码和问题描述,能感觉到你对这个思路的执着,咱们不用换整体框架,只需要修复两个关键问题就能通过所有测试用例啦:

第一个错误:误把直线当成了线段!

你在垂直线和水平线的判断里,加了一个区间检查(比如(y1 <= tempY && tempY <= y2) || (y2 <= tempY && tempY <= y1)),这是致命错误!

直线是无限延伸的,不是两点之间的线段啊!比如有个点的x和垂直线的x相同,但y值比y1和y2都大,它依然在这条垂直线上,但你的代码因为区间判断直接把它排除了,这就是你计数少了的核心原因之一。

修复方式:

直接删掉区间判断!只要坐标符合直线条件,就计数:

  • 垂直线场景:只要tempX == x1,不管y是多少,innerMax++
  • 水平线场景:只要tempY == y1,不管x是多少,innerMax++

第二个错误:浮点数精度陷阱!

你用double存储斜率m和截距b,然后用y == (m * x + b)判断点是否在直线上,这会因为浮点数的精度误差漏掉很多点。

举个例子:当斜率是1/3时,double无法精确表示这个分数,计算m*x的时候会有微小的舍入误差,导致m*x + b和y看起来不相等,但实际上点是在直线上的。

修复方式:用整数交叉相乘替代浮点数计算

对于斜线场景,我们不需要计算斜率和截距,直接用整数交叉相乘来判断点是否在直线上:
对于点(x1,y1)、(x2,y2)和待判断点(tempX,tempY),点在直线上的充要条件是:

(tempY - y1) * (x2 - x1) == (tempX - x1) * (y2 - y1)

这个公式完全用整数运算,没有任何精度损失,完美避免浮点数问题。

修改后的关键代码片段

把你代码里的斜线场景和垂直线/水平线场景修改如下:

垂直线场景修改后:

if (x1 == x2) {
    // 垂直线:只要x坐标相同就在直线上,不需要区间判断
    for (int k = 0; k < length; k++) {
        if (k == i || k == j) {
            continue;
        }
        int tempX = points[k][0];
        if (tempX == x1) {
            innerMax++;
        }
    }
}

水平线场景修改后:

else if (y1 == y2) {
    // 水平线:只要y坐标相同就在直线上,不需要区间判断
    for (int k = 0; k < length; k++) {
        if (k == i || k == j) {
            continue;
        }
        int tempY = points[k][1];
        if (tempY == y1) {
            innerMax++;
        }
    }
}

斜线场景修改后:

else {
    // 斜线:用整数交叉相乘判断,避免浮点数精度问题
    int dy = y2 - y1;
    int dx = x2 - x1;
    for (int k = 0; k < length; k++) {
        if (k == i || k == j) {
            continue;
        }
        int tempX = points[k][0];
        int tempY = points[k][1];
        // 交叉相乘判断:(y - y1)*dx == (x - x1)*dy,转long避免整数溢出
        if ((long)(tempY - y1) * dx == (long)(tempX - x1) * dy) {
            innerMax++;
        }
    }
}

注意这里要把结果转成long,避免整数溢出!比如当dx和tempY-y1都是很大的整数时,相乘会超出int的范围,导致溢出错误,转成long就没问题了。

关于官方解法的HashMap

官方解法用HashMap是为了优化重复计算:对于每个点,统计经过它的所有直线的点数,用HashMap存储不同斜率(用最简分数表示)对应的点数,这样就不用重复遍历同一条直线(比如直线ij和直线ji是同一条,不用分别计算)。但你的思路是遍历所有两两组合,虽然时间复杂度高一点(O(n³)),但逻辑是通顺的,只要修复上面两个错误就能通过所有测试用例。

内容的提问来源于stack exchange,提问作者xhbear

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:44:07