「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」。
题目描述:
976. 三角形的最大周长 - 力扣(LeetCode) (leetcode-cn.com)
给定由一些正数(代表长度)组成的数组 nums ,返回 由其中三个长度组成的、面积不为零的三角形的最大周长 。如果不能形成任何面积不为零的三角形,返回 0。
示例一
输入: nums = [2,1,2]
输出: 5
示例二
输入: nums = [1,2,1]
输出: 0
提示:
3 <= nums.length <= 10^41 <= nums[i] <= 10^6
思路分析
贪心
正常情况下,对于三条边长,判断能否组成三角形需要判断任何两条边长相加都大于其余的一条边长,即:
a + b > c && a + c > b && b + c > a
如果我们假设 , 那么这三条边组成面积不为零的三角形的充分必要条件为 。
为什么是 a + b > c ?
已知 a<=b<=c,那么必然有:
- a + c > b,因为 c >= b,那c加上一个正数一定就比b大了。而题目里说所数都>=1,所以c加上a一定比b大。
- b + c > a,因为b和c至少跟a一样大(b>=a, c>=a),加起来的结果至少有2a,即 b+c >= 2a > a
所以最终只需要判断 a + b > c 即可。
为什么只需要判断数组中相邻的三个数?
在固定最后一个数 A[i] 时,前两个数需不需要再往前找呢?
如果 A[i-2] + A[i-1] <= A[i] ,这三个数一定不能构成三角形,而A[i-3]以及更往前的数,都小于等于A[i-2],所以再往前取任何两个数只会让相加的值更小,就更不能满足 A[j] + A[k] > A[i]了 (j<i-2, k<i-1, j<k)。所以如果相邻的数构不成三角形,就不需要再固定第三个数并往前找两个数了。
如果 A[i-2] + A[i-1] > A[i]j,这三个数可以构成三角形,再往前找只会让周长变短,所以也不用再往前了。
综上,只需要判断相邻的三个数。
AC代码
import kotlin.math.abs
class Solution {
fun largestPerimeter(nums: IntArray): Int {
nums.sortDescending()
var startPos = 0
var endPos = 2
while (endPos <= nums.lastIndex) {
val first = nums[startPos]
val second = nums[startPos + 1]
val third = nums[endPos]
if (isTriangle(first, second, third)) {
return first + second + third
}
startPos++
endPos++
}
return 0
}
private fun isTriangle(first: Int, second: Int, third: Int): Boolean {
return first + second > third && abs(first - second) < third
}
}
总结
简单题我重拳出击~