LeetCode 976: Largest Perimeter Triangle (Sort + Adjacent Triangle Inequality)
LeetCode 976GreedySortingToday we solve LeetCode 976 - Largest Perimeter Triangle.
Source: https://leetcode.com/problems/largest-perimeter-triangle/
English
Problem Summary
Given an integer array nums representing side lengths, pick three lengths that can form a non-degenerate triangle and return the largest possible perimeter. If impossible, return 0.
Key Insight
After sorting ascending, if we choose three sides a <= b <= c, they form a triangle exactly when a + b > c. To maximize perimeter, we should try larger sides first, so scan from the end.
Algorithm
- Sort nums in ascending order.
- For i from n-1 down to 2, test triplet (nums[i-2], nums[i-1], nums[i]).
- If nums[i-2] + nums[i-1] > nums[i], return their sum immediately (largest possible).
- If no triplet passes, return 0.
Complexity Analysis
Time: O(n log n) (sorting dominates).
Space: O(1) extra (ignoring sorting implementation details).
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int largestPerimeter(int[] nums) {
Arrays.sort(nums);
for (int i = nums.length - 1; i >= 2; i--) {
if (nums[i - 2] + nums[i - 1] > nums[i]) {
return nums[i - 2] + nums[i - 1] + nums[i];
}
}
return 0;
}
}func largestPerimeter(nums []int) int {
sort.Ints(nums)
for i := len(nums) - 1; i >= 2; i-- {
if nums[i-2]+nums[i-1] > nums[i] {
return nums[i-2] + nums[i-1] + nums[i]
}
}
return 0
}class Solution {
public:
int largestPerimeter(vector<int>& nums) {
sort(nums.begin(), nums.end());
for (int i = (int)nums.size() - 1; i >= 2; --i) {
if (nums[i - 2] + nums[i - 1] > nums[i]) {
return nums[i - 2] + nums[i - 1] + nums[i];
}
}
return 0;
}
};class Solution:
def largestPerimeter(self, nums: List[int]) -> int:
nums.sort()
for i in range(len(nums) - 1, 1, -1):
if nums[i - 2] + nums[i - 1] > nums[i]:
return nums[i - 2] + nums[i - 1] + nums[i]
return 0var largestPerimeter = function(nums) {
nums.sort((a, b) => a - b);
for (let i = nums.length - 1; i >= 2; i--) {
if (nums[i - 2] + nums[i - 1] > nums[i]) {
return nums[i - 2] + nums[i - 1] + nums[i];
}
}
return 0;
};中文
题目概述
给定整数数组 nums 作为边长,从中选三条边组成非退化三角形,并返回可得到的最大周长;若无法组成三角形,返回 0。
核心思路
将数组升序后,对于三条边 a <= b <= c,只需检查 a + b > c。为了最大周长,应优先尝试更大的边,因此从右向左扫描三元组即可。
算法步骤
- 先将 nums 升序排序。
- 从末尾开始枚举三元组 (nums[i-2], nums[i-1], nums[i])。
- 若满足 nums[i-2] + nums[i-1] > nums[i],立刻返回三者之和(这是当前能取得的最大周长)。
- 若扫描结束仍未命中,返回 0。
复杂度分析
时间复杂度:O(n log n)(排序主导)。
空间复杂度:O(1) 额外空间(不计排序实现细节)。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int largestPerimeter(int[] nums) {
Arrays.sort(nums);
for (int i = nums.length - 1; i >= 2; i--) {
if (nums[i - 2] + nums[i - 1] > nums[i]) {
return nums[i - 2] + nums[i - 1] + nums[i];
}
}
return 0;
}
}func largestPerimeter(nums []int) int {
sort.Ints(nums)
for i := len(nums) - 1; i >= 2; i-- {
if nums[i-2]+nums[i-1] > nums[i] {
return nums[i-2] + nums[i-1] + nums[i]
}
}
return 0
}class Solution {
public:
int largestPerimeter(vector<int>& nums) {
sort(nums.begin(), nums.end());
for (int i = (int)nums.size() - 1; i >= 2; --i) {
if (nums[i - 2] + nums[i - 1] > nums[i]) {
return nums[i - 2] + nums[i - 1] + nums[i];
}
}
return 0;
}
};class Solution:
def largestPerimeter(self, nums: List[int]) -> int:
nums.sort()
for i in range(len(nums) - 1, 1, -1):
if nums[i - 2] + nums[i - 1] > nums[i]:
return nums[i - 2] + nums[i - 1] + nums[i]
return 0var largestPerimeter = function(nums) {
nums.sort((a, b) => a - b);
for (let i = nums.length - 1; i >= 2; i--) {
if (nums[i - 2] + nums[i - 1] > nums[i]) {
return nums[i - 2] + nums[i - 1] + nums[i];
}
}
return 0;
};
Comments