LeetCode探索(106):593-有效的正方形

265 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情 >>

题目

给定2D空间中四个点的坐标 p1, p2, p3p4,如果这四个点构成一个正方形,则返回 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, p3p4,如果这四个点构成一个正方形,则返回 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)。

参考