题目:
Given an array A of positive lengths, return the largest perimeter of a triangle with non-zero area, formed from 3 of these lengths.
If it is impossible to form any triangle of non-zero area, return 0.
题目原意是:给出一个正整数数组,如果其中3个数能构成三角形,那么求得:在所有满足条件的三角形中,周长最大的那个。如果不能构成三角形,则返回0
例如:
Input: [3,6,2,3]
Output: 8
Input: [1,2,1]
Output: 0
假设条件
首先,判断数据是否能够成三角形所满足的条件:
1:两边之差小于第三边
2:两边之和大于第三边
解题思路
因为涉及到前后数据的比较,首先考虑对数组A进行排序(降序)。
那么就有: A[i] >= A[i+1], 同样A[i+1] >= A[i+2],也就是A[i] >= A[i+1] >= A[i+2]
针对:两边之和大于第三边
则条件必须有:
- A[i] + A[i+1] > A[i+2]
- A[i] + A[i+2] > A[i+1]
- A[i+1] + A[i+2] > A[i]
而在数据A降序排好后,已经有了A[i] >= A[i+1] >= A[i+2],所以上述条件中前面两个一定是成立的。因此针对两边之和大于第三边的要求,我们只需要判断条件3:A[i+1] + A[i+2] > A[i]是否成立。
针对:两边之差小于第三边
则条件必须有:
4. A[i] - A[i+1] < A[i+2]
5. A[i] - A[i+2] < A[i+1]
6. A[i+1] - A[i+2] < A[i]
同样,在数据A降序排好后,A[i+1]和A[i+2] 都是小于A[i] 的,因此,条件6是一定成立的,而观察条件4和5,都是要求满足A[i] < A[i+2] + A[i+1],可以观察到,与条件3是等价的。
因此,针对两边之和大于第三边 和 两边之差小于第三边 这两个要求,降序排好后的数据,都必须满足一个条件:A[i] < A[i+2] + A[i+1]。
而且数组A经过降序排好后,只要发现第一次满足的3个数据,一定是求和(三角形周长)最大的,可以直接返回求和(周长最大值结果)。
Python代码
def largestPerimeter(self, A):
A = sorted(A)[::-1]
for i in range(len(A) - 2):
if A[i] < A[i + 1] + A[i + 2]:
return A[i] + A[i + 1] + A[i + 2]
return 0
Java代码
public int largestPerimeter(int[] A) {
Arrays.sort(A);
for (int i = A.length - 1; i > 1; --i)
if (A[i] < A[i - 1] + A[i - 2])
return A[i] + A[i - 1] + A[i - 2];
return 0;
}