携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情 >>
题目
给定2D空间中四个点的坐标 p1, p2, p3 和 p4,如果这四个点构成一个正方形,则返回 true 。
点的坐标 pi 表示为 [xi, yi] 。输入 不是 按任何顺序给出的。
一个 有效的正方形 有四条等边和四个等角(90度角)。
示例 1:
输入: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]
输出: True
示例 2:
输入:p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,12]
输出:false
示例 3:
输入:p1 = [1,0], p2 = [-1,0], p3 = [0,1], p4 = [0,-1]
输出:true
提示:
p1.length == p2.length == p3.length == p4.length == 2-10^4 <= xi, yi <= 10^4
思考
本题难度中等。
首先是读懂题意。对于二维平面中的四个点p1, p2, p3 和 p4,如果这四个点构成一个正方形,则返回 true ,否则返回false。
我们不难想到,可以根据数学上的正方形判定定理进行解题,比如对角线互相垂直且相等的平行四边形是正方形、一组邻边相等的矩形是正方形、有一个角是直角的菱形是正方形等。这里我们借助对角线互相垂直且相等、一组邻边相等的四边形是正方形的定理进行解题。
为了方便标记四边形的四个点,这里对四个点进行排序,其相对位置是:
2 4 2 4
1 3 1 3
我们通过函数getDistanceSquare(arr1, arr2)计算arr1和arr2两点之间的距离,通过函数isVertical(arr1, arr2, arr3, arr4)判断直线14和直线23是否互相垂直。此外,测试用例中包含了四个点的坐标均为[0, 0]的情况,所以我们要排除这种情况。至此,问题解决!
解答
方法一:数学
/**
* @param {number[]} p1
* @param {number[]} p2
* @param {number[]} p3
* @param {number[]} p4
* @return {boolean}
*/
var validSquare = function(p1, p2, p3, p4) {
let arr = [p1, p2, p3, p4].sort((a, b) => (a[0] - b[0] === 0 ? a[1] - b[1] : a[0] - b[0]))
let d14 = getDistanceSquare(arr[0], arr[3]), d23 = getDistanceSquare(arr[1], arr[2])
let d12 = getDistanceSquare(arr[0], arr[1]), d13 = getDistanceSquare(arr[0], arr[2])
return d14 === d23 && d14 !== 0 && d12 === d13 && isVertical(...arr)
}
// 求两点之间的距离的平方
function getDistanceSquare(arr1, arr2) {
return (arr2[0] - arr1[0])**2 + (arr2[1] - arr1[1])**2
}
// 判断直线14和直线23是否互相垂直
function isVertical(arr1, arr2, arr3, arr4) {
if ((arr4[1] - arr1[1] === 0) && (arr3[0] - arr2[0] === 0)) {
return true
} else {
return (arr4[1] - arr1[1]) * (arr3[1] - arr2[1]) + (arr4[0] - arr1[0]) * (arr3[0] - arr2[0]) === 0
}
}
复杂度分析:
- 时间复杂度:O(1)。
- 空间复杂度:O(1)。