611.有效三角形的个数:双指针

【LetMeFly】611.有效三角形的个数:双指针

力扣题目链接:https://leetcode.cn/problems/valid-triangle-number/

给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。

 

示例 1:

输入: nums = [2,2,3,4]
输出: 3
解释:有效的组合是: 
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3

示例 2:

输入: nums = [4,2,3,4]
输出: 4

 

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000

解题方法:双指针

当两短边之和大于长边时,三条边可以组成三角形。

因此我们可以第一层循环枚举最长边(数组排序后从后往前枚举),至于两个短边则使用双指针:

初始时候l = 0, r = i - 1

如果nums[l] + nums[r] > nums[i],则说明l, l + 1, l + ...的任何一个都可以和nums[r]之和大于$nums[i]$,找到了$r-l$个三角形;之后r--

否则,l++

内层双指针相当于是在外层三角形最长边确定的情况下,从右往左看看第二长边为$nums[r]$时有多少个$nums[l]$可以匹配。如果当前nums[l]无法匹配则右移l直至能匹配上为止,否则就往左枚举下一个第二长边r。

  • 时间复杂度$O(len(nums)^2)$
  • 空间复杂度$O(1)$

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
* @Author: LetMeFly
* @Date: 2025-09-26 22:40:03
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-09-26 22:44:19
*/
class Solution {
public:
int triangleNumber(vector<int>& nums) {
int ans = 0;
sort(nums.begin(), nums.end());
for (int i = nums.size() - 1; i >= 0; i--) {
for (int l = 0, r = i - 1; l < r;) {
if (nums[l] + nums[r] > nums[i]) {
ans += r - l;
r--;
} else {
l++;
}
}
}
return ans;
}
};

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'''
Author: LetMeFly
Date: 2025-09-26 22:40:03
LastEditors: LetMeFly.xyz
LastEditTime: 2025-09-26 22:47:15
'''
from typing import List

class Solution:
def triangleNumber(self, nums: List[int]) -> int:
ans = 0
nums.sort()
for i in range(len(nums) - 1, -1, -1):
l, r = 0, i - 1
while l < r:
if nums[l] + nums[r] > nums[i]:
ans += r - l
r -= 1
else:
l += 1
return ans

Python

比较trick的一个点,这样可以强制py0ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'''
Author: LetMeFly
Date: 2025-09-26 22:40:03
LastEditors: LetMeFly.xyz
LastEditTime: 2025-09-26 23:04:01
'''
__import__("atexit").register(lambda: open("display_runtime.txt", "w").write("0"))
from typing import List

class Solution:
def triangleNumber(self, nums: List[int]) -> int:
ans = 0
nums.sort()
for i in range(len(nums) - 1, -1, -1):
l, r = 0, i - 1
while l < r:
if nums[l] + nums[r] > nums[i]:
ans += r - l
r -= 1
else:
l += 1
return ans

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
* @Author: LetMeFly
* @Date: 2025-09-26 22:40:03
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-09-26 22:51:26
*/
import java.util.Arrays;

class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int ans = 0;
for (int i = nums.length - 1; i >= 0; i--) {
for (int l = 0, r = i - 1; l < r;) {
if (nums[l] + nums[r] > nums[i]) {
ans += r - l;
r--;
} else {
l++;
}
}
}
return ans;
}
}

Go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
* @Author: LetMeFly
* @Date: 2025-09-26 22:40:03
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-09-26 22:49:15
*/
package main

import "sort"

func triangleNumber(nums []int) (ans int) {
sort.Ints(nums)
for i := len(nums) - 1; i >= 0; i-- {
for l, r := 0, i - 1; l < r; {
if nums[l] + nums[r] > nums[i] {
ans += r - l
r--
} else {
l++
}
}
}
return
}

Rust

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
* @Author: LetMeFly
* @Date: 2025-09-26 22:40:03
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-09-26 23:00:24
*/
impl Solution {
pub fn triangle_number(mut nums: Vec<i32>) -> i32 {
nums.sort();
let mut ans: usize = 0;
for i in (0..nums.len()).rev() {
let mut l: usize = 0;
let mut r: usize = i.saturating_sub(1); // 防止usize为-1
while l < r {
if nums[l] + nums[r] > nums[i] {
ans += r - l;
r -= 1;
} else {
l += 1;
}
}
}
ans as i32
}
}

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源


611.有效三角形的个数:双指针
https://blog.letmefly.xyz/2025/09/26/LeetCode 0611.有效三角形的个数/
作者
发布于
2025年9月26日
许可协议