leetcode1232.缀点成线(C/C++/Java/python)

PS:算法并非原创,仅作个人学习记录使用,侵删

题目描述
在这里插入图片描述

算法分析
这道题目看起来难度不高,判断多点共线问题似乎是高中数学里面就学过的算法思路。
所以一开始,我的算法思路和斜率有关。
可以根据“两点确定一条直线”,可以算出一个参考的斜率,根据参考的斜率预测下一个坐标点的位置(可以已知x坐标求y坐标)。
或者每个点都和第一个点进行斜率计算,得出的结果如果总是相同,则多点共线。

而大佬们的算法博客中,思路基本上也是如此:
计算第i个点、第i-1个点、第i+1个点之间的斜率;【Java解法、C语言解法】
计算第0个点、第1个点、第i个点之间的斜率;【python解法】
利用直线方程进行求解【C++解法】

此外,需要注意的是,比较斜率时,为了避免除0这种特殊错误的产生,可以将除法式转化为乘法式,当这样比较斜率时,也可以说是运用了向量共线的基本性质。

代码实现
【C】

/*
采用向量之间的叉乘做法:
 * 叉乘 a * b
 * = | x1, y1 | = x1 * y2 - y1 * x2
 *   | x2, y2 |
 * 若结果小于 0,表示向量 b 在向量 a 的顺时针方向;
 * 若结果大于 0,表示向量 b 在向量 a 的逆时针方向;
 * 若结果为 0,表示向量 b 与向量 a 平行;
 */
bool checkStraightLine(int** coordinates, int coordinatesSize, int* coordinatesColSize)
{
    int x1 = coordinates[1][0] - coordinates[0][0];
    int y1 = coordinates[1][1] - coordinates[0][1];

    for (int i = 2; i < coordinatesSize; ++i) {
        int x2 = coordinates[i][0] - coordinates[0][0];
        int y2 = coordinates[i][1] - coordinates[0][1];
        if (x1 * y2 != x2 * y1) {//和比较斜率很相似,比较的是第i个、第0个、第1个点之间的斜率是否相同。
            return false;
        }
    }

    return true;
}

C语言参考网址

【C++】

/*
采用直线方程的求解方法。
设定一个线性方程,代入点坐标求解系数,得到一条参考的直线,之后在印证其他的点是不是在这条直线上。
为了线性方程的系数求解简单,该解法中先做了平移,简化直线方程
*/
class Solution {
public:
    bool checkStraightLine(vector<vector<int>> &coordinates) {
        int deltaX = coordinates[0][0], deltaY = coordinates[0][1];//平移程度
        int n = coordinates.size();
        for (int i = 0; i < n; ++i) {//将所有的点进行平移,数组中第一点此时位于原点,这样做是为了简化方程。
            coordinates[i][0] -= deltaX;
            coordinates[i][1] -= deltaY;
        }
        int A = coordinates[1][1], B = -coordinates[1][0];//Ax+By=0的方程中,带入point[0]和point[1],得到A、B两个系数大小。
        for (int i = 2; i < n; ++i){//对于point[2]及之后的点,进行直线位置判断
            int x = coordinates[i][0], y = coordinates[i][1];
            if (A * x + B * y != 0) {
                return false;
            }
        }
        return true;
    }
};

C++参考网址

【Java】

/*
利用斜率进行判断,如果相邻线段之间斜率总是相等,则点共线
*/
class Solution {
    public boolean checkStraightLine(int[][] coordinates) {
        int len = coordinates.length;
        for (int i = 1; i < len - 1; ++i) {//遍历点坐标数组
            int y1 = coordinates[i][1] -coordinates[i-1][1];//第i个点和第i-1个点之间的纵坐标差
            int x1 = coordinates[i][0] -coordinates[i-1][0];//第i个点和第i-1个点之间的横坐标差
            int y2 = coordinates[i+1][1] -coordinates[i][1]; //第i+1个点和第i个点之间的纵坐标差        
            int x2 = coordinates[i+1][0] -coordinates[i][0];//第i+1个点和第i个点之间的横坐标差
            if (y1*x2 != y2*x1) {//y1/x1 y2/x2是两个斜率,此处进行化简,也就是判断两线段斜率是否相同,如果不同,则不共线
                return false;
            }
        }
        return true;

    }
}

Java参考网址

【python】

#比较第0个,第1个和第i个点的斜率
class Solution:
    def checkStraightLine(self, coordinates):
        
        for i in range(2,len(coordinates)):
            if (coordinates[i][1] - coordinates[1][1])*(coordinates[1][0]-coordinates[0][0])  != (coordinates[1][1] - coordinates[0][1]) * (coordinates[i][0] - coordinates[1][0]):#将除法转为乘法,目的是为了避免除0的情况
                return False
        return True
        

python参考网址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值