缀点成线

256 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目描述

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

示例1:

image.png

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

示例2:

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 中不含重复的点

二、思路分析

题目给出的题意已是十分清楚,就是需要我们判断给出所有的点是否共线,我们都知道两点确定一条直线,所以解题的思路就很简单了不是吗?

  • 1、确定直线方程
  • 2、遍历坐标点列表,判断是否在直线上 那么我们要怎么确定一条直线的方程呢?这里就要复习一下我们小学四年级学过的这些基础直线公式了。
  • (1)一般式:Ax+By+C=0(A、B不同时为0)【适用于所有直线】
    A1/A2=B1/B2≠C1/C2←→两直线平行 A1/A2=B1/B2=C1/C2←→两直线重合 横截距a=-C/A 纵截距b=-C/B
  • (2)点斜式:y-y0=k(x-x0) 【 适用于不垂直于x轴的直线 】 表示斜率为k,且过(x0,y0)的直线
  • (3)截距式:x/a+y/b=1【适用于不过原点或不垂直于x轴、y轴的直线】 表示与x轴、y轴相交,且x轴截距为a,y轴截距为b的直线
  • (4)斜截式:y=kx+b【适用于不垂直于x轴的直线】 表示斜率为k且y轴截距为b的直线
  • (5)两点式:【适用于不垂直于x轴、y轴的直线】 两点式
    两点式表示过(x1,y1)和(x2,y2)的直线 
    (y-y1)/(y2-y1)=(x-x1)/(x2-x1) ( x1≠x2,y1≠y2 )
  • (6)交点式:f1(x,y) *m+f2(x,y)=0 【适用于任何直线】 表示过直线f1(x,y)=0与直线f2(x,y)=0的交点的直线

以上即为比较常见的一些求直线方程的公式 我们可以从中选择一种方式来进行解题,因为题目给出的坐标点数大于等于2,所以这里我选择了两点式的方法来进行解题,这里需要注意一个点,我们不能直接使用以下方法来进行判断。

if((y-y1)/(y2-y1)!=(x-x1)/(x2-x1)) return false;

因为除法运算中被除数不能为零,但被除数为0时得出的结果会是NaN,这时候得出的答案就不准确了,我们可以这样做

if((y-y1)*(x2-x1)!==(x-x1)*(y2-y1)) return false;

将除法转换为乘法也就不需要去特殊处理被除数为0的情况了。

AC代码

/**
 * @param {number[][]} coordinates
 * @return {boolean}
 */
var checkStraightLine = function(coordinates) {
    let x1 = coordinates[0][0],x2 = coordinates[1][0];
    let y1 = coordinates[0][1],y2 = coordinates[1][1];
    for(let i = 2; i < coordinates.length; i++){
        let x = coordinates[i][0],y = coordinates[i][1];
        if((y-y1)*(x2-x1)!==(x-x1)*(y2-y1)) return false;
    }
    return true;
};