三角形的最大周长

标签: 贪心 数组 数学 排序

难度: Easy

给定由一些正数(代表长度)组成的数组 nums ,返回 由其中三个长度组成的、面积不为零的三角形的最大周长 。如果不能形成任何面积不为零的三角形,返回 0

示例 1:

输入:nums = [2,1,2]
输出:5
解释:你可以用三个边长组成一个三角形:1 2 2。

示例 2:

输入:nums = [1,2,1,10]
输出:0
解释:
你不能用边长 1,1,2 来组成三角形。
不能用边长 1,1,10 来构成三角形。
不能用边长 1、2 和 10 来构成三角形。
因为我们不能用任何三条边长来构成一个非零面积的三角形,所以我们返回 0。

提示:

  • 3 <= nums.length <= 104
  • 1 <= nums[i] <= 106

Submission

运行时间: 36 ms

内存: 17.0 MB

class Solution:
    def largestPerimeter(self, nums: List[int]) -> int:
        nums.sort()
        for i in range(len(nums)-1,1,-1):
            if nums[i]<nums[i-1]+nums[i-2]:
                return nums[i]+nums[i-1]+nums[i-2]
        return 0

Explain

为了形成一个非零面积的三角形,任意两边之和必须大于第三边。这可以通过排序数组确保最大的两个数的和大于第三个数来达成。首先对数组排序,然后从数组的末尾开始,检查每一组连续的三个数是否能形成一个三角形。检查的条件是:若第三大的数和第二大的数之和大于最大的数,则这三个数可以构成三角形。如果找到这样的组合,则返回这三个数的和作为最大周长。如果遍历结束仍未找到有效的三角形,则返回0。

时间复杂度: O(n log n)

空间复杂度: O(1)

# 定义一个类Solution
class Solution:
    # 定义函数largestPerimeter,接收一个列表nums
    def largestPerimeter(self, nums: List[int]) -> int:
        # 首先对列表进行排序
        nums.sort()
        # 从最大的元素开始向前检查每一组连续的三个元素
        for i in range(len(nums)-1, 1, -1):
            # 检查能否形成三角形,即两边之和是否大于第三边
            if nums[i] < nums[i-1] + nums[i-2]:
                # 如果可以,返回这三个数的和作为最大周长
                return nums[i] + nums[i-1] + nums[i-2]
        # 如果没有找到任何可以形成三角形的组合,返回0
        return 0

Explore

从数组的最大值开始向前检查可以快速找到可能的最大周长的三角形。因为三角形的周长是由边长决定的,如果我们从最大的数开始检查,能够确保一旦找到符合条件的三个数,它们的周长一定是所有可能三角形中最大的。这种方法效率高,并且避免了不必要的检查。

根据三角形的形成条件,任意两边之和必须大于第三边。在算法中,通过检查排序后连续的三个数,确保第三大的数和第二大的数之和大于最大的数,来保证这三个数可以形成一个非零面积的三角形。因为如果两边之和仅等于第三边,三角形就会退化成一条线,面积为零。

是的,该算法能够正确判断是否能形成至少一个有效的三角形。算法通过系统地检查所有可能的连续三个数的组合,确保没有遗漏。如果数组中存在至少一组能形成三角形的三个数,算法会返回最大的周长。如果没有找到任何有效组合,则返回0,表示无法形成三角形。

在数组中存在相同长度的边并不会影响算法的判断逻辑或结果。算法只关心是否满足三角形的形成条件,即任意两边之和大于第三边。相同长度的边可以参与形成三角形,只要它们与其他边组合满足条件。因此,相同长度的边只会扩大可能形成三角形的组合数量,而不会影响算法的基本逻辑。