LeetCode.1232 缀点成线

197 阅读2分钟

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」。

题目描述:

1232. 缀点成线 - 力扣(LeetCode) (leetcode-cn.com)

给定一个数组 coordinates ,其中 coordinates[i] = [x, y] , [x, y] 表示横坐标为 x、纵坐标为 y 的点。请你来判断,这些点是否在该坐标系中属于同一条直线上。

示例一

image.png

输入: coordinates = [[1,2],[2,3],[3,4],[4,5],[5,6],[6,7]]
输出: true

示例二

image.png

示例三

输入: coordinates = [[1,1],[2,2],[3,4],[4,5],[5,6],[7,7]]
输出: false

提示:

  • 2 <= coordinates.length <= 1000
  • coordinates[i].length == 2
  • -10^4 <= coordinates[i][0], coordinates[i][1] <= 10^4
  • coordinates 中不含重复的点

思路分析

数学法

根据我们小学的数学知识即可知道,在给定的点集中,以任意一点 P0P_0为基准,如果其他点的 ΔyΔx\dfrac{\Delta y}{\Delta x}是不变的,那么点集内所有的点在同一条直线上。

但是如果这些点连成的线是垂直于 xx 轴的,即 Δx\Delta x 为0,即涉及到除数为 00 的问题,需要单独判断。所以我们换个数学法。

我们可以把点集中除了 P0P_0 之外的点 PiP_i 都看成以 P0P_0为起点、PiP_i 为终点的向量,记为 viv_i,并选择 v1v_1 作为基准。如果其他向量都与 v1v_1 共线,那么点集内所有的点共线。

这里需要用到线性代数的基础知识:如果二维向量 α\alphaβ\beta 共线,那么它们线性相关,且有:

α,β=0|\alpha,\beta|=0,即它们拼成的二阶矩阵的行列式为 00

AC代码

class Solution {
    public boolean checkStraightLine(int[][] coordinates) {
        int deltaX = coordinates[0][0], deltaY = coordinates[0][1];
        int n = coordinates.length;
        for (int i = 0; i < n; i++) {
            coordinates[i][0] -= deltaX;
            coordinates[i][1] -= deltaY;
        }
        int A = coordinates[1][1], B = -coordinates[1][0];
        for (int i = 2; i < n; i++) {
            int x = coordinates[i][0], y = coordinates[i][1];
            if (A * x + B * y != 0) {
                return false;
            }
        }
        return true;        
    }
}

总结

同样的算法,用向量线性相关性来解释,逼格立马提升了N个档次 - -

参考

缀点成线 - 缀点成线 - 力扣(LeetCode) (leetcode-cn.com)

尽量不要用判断斜率是否相等,可以利用共线向量线性相关 - 缀点成线 - 力扣(LeetCode) (leetcode-cn.com)