有效三角形的个数-LeetCode
611. 有效三角形的个数
🎯 问题描述(来源于LeetCode)
描述:
给定一个包含非负整数的数组 nums,返回其中可以组成三角形三条边的三元组个数。
三角形的条件是:任意两边之和大于第三边,等价于较短两边之和大于最长边。
说明:
- 三元组
(i, j, k)满足i < j < k,且nums[i] + nums[j] > nums[k]。 - 数组长度
1 <= n <= 1000。
示例:
- 示例 1:
1 | 输入: nums = [2,2,3,4] |
- 示例 2:
1 | 输入: nums = [4,2,3,4] |
💻 解题思路
思路:排序 + 双指针(固定最短边,滑动中边)
算法步骤
- 将数组
nums升序排序。 - 外层循环
slow从 0 到n-3,固定最短边num = nums[slow]。
如果num == 0,由于三角形边长必须为正数,直接跳过。 - 初始化
mid = slow + 1,指向可能的次短边(中边)的起始位置。 - 内层循环
fast从slow+2到n-1,枚举最长边c = nums[fast]:- 当
nums[fast] - nums[mid] >= num时,说明num + nums[mid] <= nums[fast],不满足三角形条件(两边之和不大于第三边)。此时将mid右移,直到满足num + nums[mid] > nums[fast]。 - 此时,所有下标从
mid到fast-1的元素都可以作为中边b,与当前的num和nums[fast]组成三角形。
可行数量为fast - mid,累加到答案ans。
- 当
- 返回
ans。
代码实现(您的代码)
1 | from typing import List |
📊 性能分析
- 时间复杂度:。外层循环 ,内层循环中
fast和mid均单调递增,每个指针最多移动 次,总体 。 - 空间复杂度:(忽略排序占用的栈空间)。
思考
您的命名 slow, mid, fast 非常形象:
slow是最短边,固定不变;fast是最长边,不断右移;mid是中边,随着fast增大和num固定,为了满足num + nums[mid] > nums[fast],mid只能向右移动,绝不回头。
利用排序后的单调性,mid 的单向移动保证了内层循环的摊还复杂度为 ,整体达到 ,这是本题的标准最优解法。跳过 0 的处理也避免了对无效边长进行多余计算,代码逻辑清晰且高效。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






