携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
前言
今天的题目为中等,题目主要就是证明题,证明四个点组成的图形是一个正方形,那么运用正方形的特性就能够得出很多种不同的解题方式,本文主要使用的是验证直角以及边长的方式来进行的。
每日一题
今天的题目是 593. 有效的正方形,难度为中等
-
给定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
- -104 <= xi, yi <= 104
题解
数学解法
要如何判断一个四边形是否是正方形,方法有特别多种,我们可以计算四条边的长度是否相等,加上一个角是否为直角,又或者四边和对边只存在两种不同的值,然后排除等边三角形组成的菱形的这种情况。
本文主要采用了计算是否含有三个直角以及三条等边的方式,只要固定好三个直角角和三条边相等,那么我们就能够确定一个正方形,所以知道了需要做什么,我们先来设计一个方法,方法传入三个点,用于计算三个点的夹角是否是直角,以及三个点组成的两条边是否相等。
function isRightAngle(a: number, b: number, c: number): boolean {
const diagonal1 = (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]);
const diagonal2 = (a[0] - c[0]) * (a[0] - c[0]) + (a[1] - c[1]) * (a[1] - c[1]);
const diagonal3 = (b[0] - c[0]) * (b[0] - c[0]) + (b[1] - c[1]) * (b[1] - c[1]);
const rightAngle =
(diagonal1 == diagonal2 && diagonal1 + diagonal2 == diagonal3) ||
(diagonal1 == diagonal3 && diagonal1 + diagonal3 == diagonal2) ||
(diagonal2 == diagonal3 && diagonal2 + diagonal3 == diagonal1);
if (!rightAngle) return false;
if (len == -1) len = Math.min(diagonal1, diagonal2);
else if (len == 0 || len != Math.min(diagonal1, diagonal2)) return false;
return true;
}
所以还需要一个变量用来存储当前的边长,至于我们要怎么判断出哪一条长度是边长呢?
取出正方形的随机三个点围成的一个直角三角形,存在三条边,随便取出两条,两条当中小的那一条就是这个正方形的边长,那么我们只要将三条边拿来做出对比,只要三条边的长度都是相等的,那么就能够得出三条边相等。
function validSquare(a: number, b: number, c: number, d: number): boolean {
let len = -1;
function isRightAngle(a: number, b: number, c: number): boolean {
const diagonal1 = (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]);
const diagonal2 = (a[0] - c[0]) * (a[0] - c[0]) + (a[1] - c[1]) * (a[1] - c[1]);
const diagonal3 = (b[0] - c[0]) * (b[0] - c[0]) + (b[1] - c[1]) * (b[1] - c[1]);
const rightAngle =
(diagonal1 == diagonal2 && diagonal1 + diagonal2 == diagonal3) ||
(diagonal1 == diagonal3 && diagonal1 + diagonal3 == diagonal2) ||
(diagonal2 == diagonal3 && diagonal2 + diagonal3 == diagonal1);
if (!rightAngle) return false;
if (len == -1) len = Math.min(diagonal1, diagonal2);
else if (len == 0 || len != Math.min(diagonal1, diagonal2)) return false;
return true;
}
return isRightAngle(a, b, c) && isRightAngle(a, b, d) && isRightAngle(a, c, d)
}