Medium
题目描述
给你一个长度为 3 的正整数数组 sides。
判断是否存在一个面积为正的三角形,其三边长度由 sides 数组的元素给出。
如果这样的三角形存在,返回一个包含三个浮点数的数组,表示其内角(以度为单位),按非递减顺序排序。否则,返回一个空数组。
答案与实际答案的误差在 10^-5 内将被接受。
示例 1:
输入:sides = [3,4,5]
输出:[36.86990,53.13010,90.00000]
解释:
你可以用边长 3、4 和 5 形成一个直角三角形。这个三角形的内角分别约为 36.869897646 度、53.130102354 度和 90 度。
示例 2:
输入:sides = [2,4,2]
输出:[]
解释:
你不能用边长 2、4 和 2 形成一个面积为正的三角形。
提示:
sides.length == 31 <= sides[i] <= 1000
解题思路
这道题需要两个步骤:验证三角形的存在性和计算内角。
第一步:三角形存在性验证 根据三角形不等式定理,三条边能够构成三角形的充分必要条件是任意两边之和大于第三边。为简化计算,我们可以先对边长排序,然后只需验证最小的两边之和是否大于最大边即可。
第二步:计算内角 如果三角形存在,使用余弦定理计算各个内角:
- 对于三边长为 a、b、c 的三角形,边 c 对应的角度为:
cos(C) = (a² + b² - c²) / (2ab) - 计算出弧度后,转换为度数:
角度 = 弧度 × 180 / π
实现细节:
- 将三边按升序排序
- 验证三角形不等式:
a + b > c - 使用余弦定理分别计算三个内角
- 将结果按升序排序后返回
时间复杂度为 O(1),空间复杂度为 O(1)。
代码实现
class Solution {
public:
vector<double> internalAngles(vector<int>& sides) {
vector<int> s = sides;
sort(s.begin(), s.end());
// 验证三角形不等式
if (s[0] + s[1] <= s[2]) {
return {};
}
double a = s[0], b = s[1], c = s[2];
// 使用余弦定理计算角度
double angleA = acos((b*b + c*c - a*a) / (2*b*c)) * 180.0 / M_PI;
double angleB = acos((a*a + c*c - b*b) / (2*a*c)) * 180.0 / M_PI;
double angleC = acos((a*a + b*b - c*c) / (2*a*b)) * 180.0 / M_PI;
vector<double> angles = {angleA, angleB, angleC};
sort(angles.begin(), angles.end());
return angles;
}
};
class Solution:
def internalAngles(self, sides: list[int]) -> list[float]:
import math
s = sorted(sides)
# 验证三角形不等式
if s[0] + s[1] <= s[2]:
return []
a, b, c = s[0], s[1], s[2]
# 使用余弦定理计算角度
angle_a = math.acos((b*b + c*c - a*a) / (2*b*c)) * 180 / math.pi
angle_b = math.acos((a*a + c*c - b*b) / (2*a*c)) * 180 / math.pi
angle_c = math.acos((a*a + b*b - c*c) / (2*a*b)) * 180 / math.pi
angles = [angle_a, angle_b, angle_c]
angles.sort()
return angles
public class Solution {
public double[] InternalAngles(int[] sides) {
Array.Sort(sides);
// 验证三角形不等式
if (sides[0] + sides[1] <= sides[2]) {
return new double[0];
}
double a = sides[0], b = sides[1], c = sides[2];
// 使用余弦定理计算角度
double angleA = Math.Acos((b*b + c*c - a*a) / (2*b*c)) * 180.0 / Math.PI;
double angleB = Math.Acos((a*a + c*c - b*b) / (2*a*c)) * 180.0 / Math.PI;
double angleC = Math.Acos((a*a + b*b - c*c) / (2*a*b)) * 180.0 / Math.PI;
double[] angles = {angleA, angleB, angleC};
Array.Sort(angles);
return angles;
}
}
var internalAngles = function(sides) {
const s = sides.slice().sort((a, b) => a - b);
// 验证三角形不等式
if (s[0] + s[1] <= s[2]) {
return [];
}
const [a, b, c] = s;
// 使用余弦定理计算角度
const angleA = Math.acos((b*b + c*c - a*a) / (2*b*c)) * 180 / Math.PI;
const angleB = Math.acos((a*a + c*c - b*b) / (2*a*c)) * 180 / Math.PI;
const angleC = Math.acos((a*a + b*b - c*c) / (2*a*b)) * 180 / Math.PI;
const angles = [angleA, angleB, angleC];
angles.sort((a, b) => a - b);
return angles;
};
复杂度分析
| 复杂度 | 大小 |
|---|---|
| 时间复杂度 | O(1) |
| 空间复杂度 | O(1) |