点击获取AI摘要

3024. 三角形类型 E

给你一个下标从 0 开始长度为 3 的整数数组 nums ,需要用它们来构造三角形。

  • 如果一个三角形的所有边长度相等,那么这个三角形称为 equilateral
  • 如果一个三角形恰好有两条边长度相等,那么这个三角形称为 isosceles
  • 如果一个三角形三条边的长度互不相同,那么这个三角形称为 scalene

如果这个数组无法构成一个三角形,请你返回字符串 "none" ,否则返回一个字符串表示这个三角形的类型。

示例 1:

输入:nums = [3,3,3]
输出:“equilateral”
解释:由于三条边长度相等,所以可以构成一个等边三角形,返回 “equilateral” 。

示例 2:

输入:nums = [3,4,5]
输出:“scalene”
解释:
nums[0] + nums[1] = 3 + 4 = 7 ,大于 nums[2] = 5 。
nums[0] + nums[2] = 3 + 5 = 8 ,大于 nums[1] = 4 。
nums[1] + nums[2] = 4 + 5 = 9 ,大于 nums[0] = 3 。
由于任意两边之和都大于第三边,所以可以构成一个三角形,因为三条边的长度互不相等,所以返回 “scalene”。

提示:

  • nums.length == 3
  • 1 <= nums[i] <= 100

问题分析

给定三个正整数边长 nums[0], nums[1], nums[2],判断它们能否构成三角形。如果不能,返回 "none";如果可以,再根据三边相等情况返回对应类型:

  • 三条边相等 → equilateral
  • 正好两条边相等 → isosceles
  • 三条边互不相等 → scalene

算法思路

首先,对这三个边长进行排序(标签:排序),记为 a ≤ b ≤ c。排序不仅能让后续判断更清晰,也方便验证三角形的必要且充分条件,只需要判断 a + b > c 即可。

如果 a + b ≤ c,则无法构成三角形,直接返回 "none"

否则,根据 a, b, c 三者是否相等做分类:

  • 如果 a == c,说明三条边都相等,返回 "equilateral"
  • 否则如果 a == bb == c,则恰有两条相等,返回 "isosceles"
  • 否则三条边互不相等,返回 "scalene"

时间复杂度

  • nums 长度为 3 的数组排序,时间复杂度为 O(Nlogn)O(N \log n)(可以认为是常数级操作)。其余比较操作也是 O(1)O(1)。因此整体时间复杂度为 O(1)O(1)

  • 空间复杂度也为 O(1)O(1),只使用了常数级的额外变量。

代码分解

排序:对 [x, y, z] 三个数进行排序,得到 a ≤ b ≤ c。排序的本质是为了简化三角形最基本的判定:只需判断最小的两个数之和是否大于最大的数即可。此时不必反复考虑全部三种两边之和情况,因为:

a+b>c    {a+b>c,a+c>b(总是成立,因为 cb),b+c>a(总是成立,因为 ca).a + b > c \iff \begin{cases} a + b > c, \\ a + c > b \text{(总是成立,因为 } c \ge b\text{)},\\ b + c > a \text{(总是成立,因为 } c \ge a\text{)}. \end{cases}

a + b ≤ c,直接返回 "none"

否则,继续比较 a, b, c

  • a == c,三个元素全等 → equilateral
  • a == bb == c,则恰好两边相等 → isosceles
  • 否则 → scalene

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
def triangleType(self, nums: list[int]) -> str:
# 1. 排序:a <= b <= c
nums.sort()
a, b, c = nums[0], nums[1], nums[2]

# 2. 三角形的必要且充分条件:最短两边之和要大于最长边
if a + b <= c:
return "none"

# 3. 根据相等情况分类
if a == c:
# a == b == c
return "equilateral"
if a == b or b == c:
# 恰有两条边相等
return "isosceles"
# 三条边互不相等
return "scalene"

因为输入规模固定且极小,性能开销几乎忽略不计;若后续需要对大量三元组进行批量判定,也可以把这段逻辑放到循环或向量化环境中(如 NumPy)来做批量处理,但基本思路一致。

若需要校验输入是否全是正整数,也可在最前面加一步验证,比如 if min(nums) < 1: return "none",但题目已保证 1 <= nums[i] <= 100,故此处略去。