说在前面
🎈每天进行一道算法题目练习,今天的题目是“有效的回旋镖”。
问题描述
给定一个数组 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
提示:
points.length == 3
points[i].length == 2
0 <= xi, yi <= 100
思路分析
阅读完题目之后,我们可以知道题目的意思:给我们三个点,我们需要判断这三个点是否满足以下条件:
- 1、三个点各不相同;
- 2、三个点不在一条直线上。
所以我们最直接的做法就是直接按照题目要求的条件对三个点进行判断即可。\
当然我们也还有其他做法:\
我们都知道3个不共线的点可以组成一个三角形,那么我们是不是也可以根据三角形的相关性质和公式来进行解题呢?\
还有我们可以使用高中都学过的知识:向量叉乘
也可以帮助我们完成这道题目。\
具体代码在后面,我们继续往下看。
AC代码
1、暴力法
直接的做法就是直接按照题目要求的条件对三个点进行判断即可。
- 1、三个点各不相同;
先对给出的点列表排序,判断相邻的点是否重合。
- 2、三个点不在一条直线上。
判断相邻两个点组成的直线斜率是否相等。
/**
* @param {number[][]} points
* @return {boolean}
*/
var isBoomerang = function(points) {
const p = points.sort((a,b)=>{
return a[0] == b[0] ? (a[1] - b[1]) : (a[0] - b[0]);
});
if((p[0][0] == p[1][0] && p[0][1] == p[1][1]) || (p[1][0] == p[2][0] && p[1][1] == p[2][1])) return false;
return !((p[0][1] - p[1][1]) * (p[1][0] - p[2][0]) == (p[1][1] - p[2][1]) * (p[0][0] - p[1][0]))
};
2、向量叉乘法
我们可以将3个点分别看成p1、p2、p3,可以将(p2-p1)看成向量v1,将(p3 - p2)看成向量v2,三点各不相同且不在一条直线上等价于这两个向量的叉乘结果不为零。
二维向量叉乘公式a(x1,y1),b(x2,y2),则 a × b=(x1 y2 - x2 y1)。
/**
* @param {number[][]} points
* @return {boolean}
*/
var isBoomerang = function(points) {
const v1 = [points[1][0] - points[0][0], points[1][1] - points[0][1]];
const v2 = [points[2][0] - points[1][0], points[2][1] - points[1][1]];
return v1[0] * v2[1] - v1[1] * v2[0] != 0;
};
3、三角形相关公式
设三个点A、B、C的坐标分别为A(x1,y1)、B(x2,y2)、C(x3、y3)
。
那么A、B、C三点可围成一个三角形。AC与AB边的夹角为∠A。
那么向量AB=(x2-x1,y2-y1)
、向量AC=(x3-x1,y3-y1)
。
令向量AB=a
,向量AC=b
,
则根据向量运算法则可得,
|a·b|=|a|·|b|·|cosA|
,
那么cosA=|a·b|/(|a|·|b|)
,则sinA=√((|a|·|b|)^2-(|a·b|)^2)/(|a|·|b|)
。
那么三角形的面积S=|a|·|b|·sinA=√((|a|·|b|)^2-(|a·b|)^2)
又a·b=(x2-x1)*(x3-x1)+(y2-y1)*(y3-y1)
,
那么可得三角形的面积S=(x1y2-x1y3+x2y3-x2y1+x3y1-x2y2)
。
/**
* @param {number[][]} points
* @return {boolean}
*/
var isBoomerang = function(points) {
return (p[0][0] * (p[1][1] - p[2][1]) + p[1][0] * (p[2][1] - p[0][1]) + p[2][0] * (p[0][1] - p[1][1])) != 0;
};
说在后面
🎉这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,平时也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。