LeetCode1232---缀点成线

    今天在LeetCode上做题有一点收获,特在此记录一下。那是一道简单题,简单描述,它给我一些点,我们判断这些点是不是都在一条直线上。(题目和链接见文章末)。

    我首先考虑的就是先求前两个点的斜率,然后分别求后面所有点与第一个点的斜率,比较是否相等,如果不相等就直接返回false。若到了最后都相等,就返回true。在这里,要求斜率,则要求做除法,而除法则需要判断分子是否为0.所以我的具体做法是这样的:

    1、判断第一个点和第二个点横坐标是否一样。如果一样,则进入2。如果不一样,则进入3。
    2、判断剩下的点横坐标是否和第一个点一样,如果中途不一样,则返回false。否则结束后返回true。
    3、计算第一个点和第二个点的斜率K,并分别计算剩下的点与第一个点的斜率 K i K_i Ki并判断是否和K相等。如果中途不相等,则返回false,否则结束后返回true。

我的解决方案如下:

class Solution {
    
    
public:
    bool checkStraightLine(vector<vector<int>>& coordinates) {
    
    
        int len = coordinates.size();
        if(len <= 2)
            return true;
        if(coordinates[0][0] == coordinates[1][0])//如果前两个数x相同,则判读后面的数x是否都和第一个相同
        {
    
    
            for(int i = 2;i < len;++i)
                if(coordinates[i][0] != coordinates[0][0])
                    return false;
        }
        else
        {
    
    
            //计算两点的斜率,然后判断后面每个点和第一个点的斜率,如果出现不相同则false
            float k = (coordinates[1][1] - coordinates[0][1]) * 1.0 / (coordinates[1][0] - coordinates[0][0]);
            for(int i = 2;i < len;++i)
            {
    
    
                if((coordinates[i][1] - coordinates[0][1]) * 1.0 / (coordinates[i][0] - coordinates[0][0]) != k)
                    return false;
            }
        }
        return true;
    }
};

    做完题目后我去看了一下题解,发现了一个很有意思的做法,可以避免算除法和除0的判断。实际上他只是做了一个很巧妙的变换,后面我们不再判断斜率是否相等,而是对斜率的式子做一个变形。比如我们原来判断的是 ( y 2 − y 1 ) / ( x 2 − x 1 ) = = ( y i − y 1 ) / ( x i − x 1 ) (y_2 - y_1)/(x_2 - x_1) ==(y_i - y_1)/(x_i - x_1) (y2y1)/(x2x1)==(yiy1)/(xix1) ,现在对它交叉相乘,判断 ( y 2 − y 1 ) ∗ ( x i − x 1 ) = = ( y i − y 1 ) ∗ ( x 2 − x 1 ) (y_2 - y_1)*(x_i - x_1)==(y_i - y_1)*(x_2-x_1) (y2y1)(xix1)==(yiy1)(x2x1).下面是改造过后的解决方案:

class Solution {
    
    
public:
    bool checkStraightLine(vector<vector<int>>& coordinates) {
    
    
        int len = coordinates.size();
        if(len <= 2)
            return true;
        //为了避免除法和除零的判断,可以转变为乘法,乘法效率比除法高
        int preDx = coordinates[1][0] - coordinates[0][0],preDy = coordinates[1][1] - coordinates[0][1],dx,dy;
        for(int i = 2;i < len;++i)
        {
    
    
            dx = coordinates[i][0] - coordinates[0][0];
            dy = coordinates[i][1] - coordinates[0][1]; 
            if(dy * preDx != dx * preDy)
                return false;
        }
        return true;
    }
};

    这一道题倒不是说后面的方法在效率上有多大提升,而是让我学会了思维的灵活转变,正着不行反着来,除法不行做个变换变成乘法,有时候做什么事也是如此,如果往一个方向一直得不到好的结果,不妨逆向思考一下,也许会有不一样的体会。

原题及链接:
在一个 XY 坐标系中有一些点,我们用数组 coordinates 来分别记录它们的坐标,其中 coordinates[i] = [x, y] 表示横坐标为 x、纵坐标为 y 的点。

请你来判断,这些点是否在该坐标系中属于同一条直线上,是则返回 true,否则请返回 false。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-if-it-is-a-straight-line

示例一:
在这里插入图片描述

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

示例二:
在这里插入图片描述

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

猜你喜欢

转载自blog.csdn.net/l1606468155/article/details/103981846