给定一个包含非负整数的数组
nums
,返回其中可以组成三角形三条边的三元组个数。
补充:
1.三角形的判断:假设有三条边按大小排序:
示例 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
分析题目可知是要算上重复的
时间复杂度较高O(3*n^3)
三层for循环确定三条边,再定义一个计数器计算有小三角形的个数
//暴力枚举
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int count=0;
int len=nums.length;
for(int i=0;inums[k])
{
count++;
}
}
}
}
return count;
}
集美们,不用跑了,我帮你们试过了,过不了
利用单调性和双指针的方法:
举个例子:
2,2,3,4,5,6,7,8,9,10
1.设置一个最大值
2.在最大数的左区间内,使用双指针和单调性的方法计算出有效三角形的个数
本宝宝建议你自己画一画,真正理解这个算法。
会出现两种情况:
①left+right>max count+=right-left right--
②left+right=
代码实现:
public int triangleNumber(int[] nums) {
int len=nums.length;
int count=0;
for(int i=len-1;i>=0;i--)
{
int max=nums[i];
int left=0;
int right=i-1;
while (leftmax)
{
count+=right-left;
right--;
}
else
{
left++;
}
}
}
return count;
}
当然这个代码你是跑不过的,为什么呢?
因为你无法确定最大值,我举的栗子正好是我排过序的,若是没有排过序,不仅找不到最大值,还无用大学生的方法判断是否是有效三角形,所以一定要先排序(这都是姐走过的弯路)
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int len=nums.length;
int count=0;
for(int i=len-1;i>=0;i--)
{
int max=nums[i];
int left=0;
int right=i-1;
while (leftmax)
{
count+=right-left;
right--;
}
else
{
left++;
}
}
}
return count;
}
本题完,欢迎指正