LC 593. 有效的正方形

题目描述

这是 LeetCode 上的 593. 有效的正方形 ,难度为 中等

给定 2D 空间中四个点的坐标 a, b, cd,如果这四个点构成一个正方形,则返回 true

点的坐标表示为 $[x_i, y_i]$ ,输入不是按任何顺序给出的。

一个有效的正方形有四条等边和四个等角(90度角)。

示例 1:

1
2
3
输入: a = [0,0], b = [1,1], c = [1,0], d = [0,1]

输出: True

示例 2:
1
2
3
输入:a = [0,0], b = [1,1], c = [1,0], d = [0,12]

输出:false

示例 3:
1
2
3
输入:a = [1,0], b = [-1,0], c = [0,1], d = [0,-1]

输出:true

提示:

  • $a.length == b.length == c.length == d.length == 2$
  • $-10^4 <= x_i, y_i <= 10^4$

计算几何

根据题意进行模拟即可。

从给定的 $4$ 个顶点中选 $3$ 个顶点,检查其能否形成「直角三角形」,同时保存下来首个直角三角形的直角边边长,供后续其余直角三角形进行对比(注意不能共点,即直角边长不能为 $0$)。

Java 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
long len = -1;
public boolean validSquare(int[] a, int[] b, int[] c, int[] d) {
return calc(a, b, c) && calc(a, b, d) && calc(a, c, d) && calc(b, c, d);
}
boolean calc(int[] a, int[] b, int[] c) {
long l1 = (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]);
long l2 = (a[0] - c[0]) * (a[0] - c[0]) + (a[1] - c[1]) * (a[1] - c[1]);
long l3 = (b[0] - c[0]) * (b[0] - c[0]) + (b[1] - c[1]) * (b[1] - c[1]);
boolean ok = (l1 == l2 && l1 + l2 == l3) || (l1 == l3 && l1 + l3 == l2) || (l2 == l3 && l2 + l3 == l1);
if (!ok) return false;
if (len == -1) len = Math.min(l1, l2);
else if (len == 0 || len != Math.min(l1, l2)) return false;
return true;
}
}

C++ 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
long len = -1;
bool validSquare(vector<int>& a, vector<int>& b, vector<int>& c, vector<int>& d) {
return calc(a, b, c) && calc(a, b, d) && calc(a, c, d) && calc(b, c, d);
}
bool calc(vector<int>& a, vector<int>& b, vector<int>& c) {
long l1 = (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]);
long l2 = (a[0] - c[0]) * (a[0] - c[0]) + (a[1] - c[1]) * (a[1] - c[1]);
long l3 = (b[0] - c[0]) * (b[0] - c[0]) + (b[1] - c[1]) * (b[1] - c[1]);
bool ok = (l1 == l2 && l1 + l2 == l3) || (l1 == l3 && l1 + l3 == l2) || (l2 == l3 && l2 + l3 == l1);
if (!ok) return false;
if (len == -1) len = min(l1, l2);
else if (len == 0 || len != min(l1, l2)) return false;
return true;
}
};

Python 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def validSquare(self, a: list, b: list, c: list, d: list) -> bool:
length = -1
def calc(a, b, c):
nonlocal length
l1 = (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2
l2 = (a[0] - c[0]) ** 2 + (a[1] - c[1]) ** 2
l3 = (b[0] - c[0]) ** 2 + (b[1] - c[1]) ** 2
ok = (l1 == l2 and l1 + l2 == l3) or (l1 == l3 and l1 + l3 == l2) or (l2 == l3 and l2 + l3 == l1)
if not ok: return False
if length == -1: length = min(l1, l2)
elif length == 0 or length != min(l1, l2): return False
return True
return calc(a, b, c) and calc(a, b, d) and calc(a, c, d) and calc(b, c, d)

TypeScript 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let len = -1
function validSquare(a: number[], b: number[], c: number[], d: number[]): boolean {
len = -1
return calc(a, b, c) && calc(a, b, d) && calc(a, c, d) && calc(b, c, d)
};
function calc(a: number[], b: number[], c: number[]): boolean {
const l1 = (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1])
const l2 = (a[0] - c[0]) * (a[0] - c[0]) + (a[1] - c[1]) * (a[1] - c[1])
const l3 = (b[0] - c[0]) * (b[0] - c[0]) + (b[1] - c[1]) * (b[1] - c[1])
const ok = (l1 == l2 && l1 + l2 == l3) || (l1 == l3 && l1 + l3 == l2) || (l2 == l3 && l2 + l3 == l1)
if (!ok) return false
if (len == -1) len = Math.min(l1, l2)
else if (len == 0 || len != Math.min(l1, l2)) return false
return true
}

  • 时间复杂度:$O(1)$
  • 空间复杂度:$O(1)$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.593 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。