持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
题目描述
给定一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点,如果这些点构成一个 回旋镖 则返回 true 。
回旋镖 定义为一组三个点,这些点 各不相同 且 不在一条直线上 。
示例 1:
输入:points = [[1,1],[2,3],[3,2]]
输出:true
示例 2:
输入:points = [[1,1],[2,2],[3,3]]
输出:false
思路
本题就是判断三点是否共线的数学题。自然而然的思路是,先判断是否存在重合的点,然后再判断两两组成的线段斜率是否相等。如果存在重合的点,按照题意就返回false。判断两两点连接处的直线的斜率的时候,要注意其中可能存在x轴值相等的情况,因为相等时,斜率是y/0,就是无穷大,就无法比较了。存在x轴值想等情况时,只有1种情况是不合法的,就是3个点的x轴值都相等,除了这种,必然能组成回旋镖。排除了点重合和x轴值相等的2种情况后,剩下3点必然没有重合也不存在斜率无穷大的情况,只要按照(y1-y0)/(x1-x0)的方法来结算斜率就好。还有一个注意点是,这里都是整数,而斜率可能是一个小数,所以通过1.0*X的方法来转换成浮点。
看了别人的题解,发现用向量夹角的方法来写就简洁多了,不用额外判断点重合和x轴值相等的情况,核心就一行代码搞定
return (ps[1][0] - ps[0][0]) * (ps[2][1] - ps[0][1]) != (ps[2][0] - ps[0][0]) * (ps[1][1] - ps[0][1]);
Java版本代码
class Solution {
public boolean isBoomerang(int[][] points) {
// 判断是否有重合点
if ((points[0][0] == points[1][0] && points[0][1] == points[1][1]) ||
(points[0][0] == points[2][0] && points[0][1] == points[2][1]) ||
(points[1][0] == points[2][0] && points[1][1] == points[2][1])) {
return false;
}
// 判断斜率
// 判断是否存在x值相等的情况,避免后面 除以0
if (points[0][0] == points[1][0] || points[0][0] == points[2][0] || points[1][0] == points[2][0]) {
// 存在x值相等的情况时,只有3个点的x值都相等,才是共线的,不合法的
if (points[0][0] == points[1][0] && points[0][0] == points[2][0]) {
return false;
} else {
return true;
}
}
// 剩下的已经排除了重合点和存在2点x轴值相等的情况,可以判断斜率是否相等,注意这里斜率可以有小数
if (1.0*(points[1][1]-points[0][1])/(points[1][0]-points[0][0]) == 1.0*(points[2][1]-points[0][1])/(points[2][0]-points[0][0])) {
return false;
} else {
return true;
}
}
}