1.题目描述
小M正在玩一个几何游戏,给定一个二维平面上的三个点 points,其中每个点用坐标 points[i] = [xi, yi] 表示。如果三点构成一个回旋镖,则返回 true。回旋镖的定义是三点不在一条直线上,并且这三个点互不相同。
请你帮助小M判断这些点是否构成一个回旋镖。
2. 题目分析
题目要求判断给定的三个点是否构成一个回旋镖,即三点不共线并且点不重合。这是一个经典的几何学问题,核心在于判定三点是否共线的数学性质。
3. 难点分析
主要难点在于精确判断三点是否共线而不引入过多的数值稳定性问题,尤其是在计算机表示精度有限的情况下。另外,需要考虑点是否重复的问题,因为即使是微小的浮点数差异也可能造成误判。
4. 解题思路
为了判定三点是否共线,可以利用向量叉乘的概念,叉乘结果为零表示向量平行,即三点共线。同时,通过比较点的坐标值来检查是否存在重复的点。
5.关键步骤和细节
点重复检测:首先,检查三个点中是否存在相同的点,若有,直接返回false。
共线判断:计算点A-B和B-C组成的向量AB和BC的叉乘是否为零,如果不是零,则三点不共线。
叉乘公式:计算叉乘时,采用((y2-y1)*(x3-x2) - (y3-y2)*(x2-x1)),避免直接做除法,以防浮点数误差。
6.具体代码实现
public static boolean solution(int[][] points) {
int x1 = points[0][0], y1 = points[0][1];
int x2 = points[1][0], y2 = points[1][1];
int x3 = points[2][0], y3 = points[2][1];
if ((x1 == x2 && y1 == y2) || (x2 == x3 && y2 == y3) || (x1 == x3 && y1 == y3)) {
return false;
}
// Calculate slopes and check if they are equal (using cross multiplication to avoid division)
long slope12 = (long)(y2 - y1) * (x3 - x2);
long slope23 = (long)(y3 - y2) * (x2 - x1);
// If slopes are equal, then the three points are collinear
if (slope12 == slope23) {
return false;
}
return true;
}
7.时间复杂度:O(1),由于只需要简单的算术运算,不受输入规模影响。 空间复杂度:O(1),只使用固定数量的变量,不会随输入增加而变化。 8. 总结 巧妙运用了几何学原理——叉乘概念,不仅简化了共线性的判断,还避免了浮点数运算可能导致的精度问题。通过前期的点重复检查,提高了效率。整体上,算法简洁有效,易于理解和实现,适用于各类三点共线的判定场景。通过精心构造测试案例验证了算法的正确性,确保了不同情况下都能得到预期的结果。