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 == 3
  • 1 <= sides[i] <= 1000

解题思路

这道题需要两个步骤:验证三角形的存在性和计算内角。

第一步:三角形存在性验证 根据三角形不等式定理,三条边能够构成三角形的充分必要条件是任意两边之和大于第三边。为简化计算,我们可以先对边长排序,然后只需验证最小的两边之和是否大于最大边即可。

第二步:计算内角 如果三角形存在,使用余弦定理计算各个内角:

  • 对于三边长为 a、b、c 的三角形,边 c 对应的角度为:cos(C) = (a² + b² - c²) / (2ab)
  • 计算出弧度后,转换为度数:角度 = 弧度 × 180 / π

实现细节:

  1. 将三边按升序排序
  2. 验证三角形不等式:a + b > c
  3. 使用余弦定理分别计算三个内角
  4. 将结果按升序排序后返回

时间复杂度为 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)