leetcode刷题记录-593. 有效的正方形

1,253 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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)
}

image.png