给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。
示例 1:
输入: [2,2,3,4]
输出: 3
解释:
有效的组合是:
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3
注意:
数组长度不超过1000。
数组里整数的范围为 [0, 1000]。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-triangle-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一个有效的三角形里任意两边加起来要比第三边长。这个暴力解法利用这个规则。里外循环遍历数组三遍,最里面那层循环检查是否任意两边加起来要比第三边长,如果是,说明我们找到了一个有效的三角形并递增结果。
时间复杂度: O(n^3) 因为有三层循环,所以是n^3的复杂度
空间复杂度: O(1)
二分查找:
暴力求解时间复杂度太高效率太低,可以试试其他方法。二分查找就是其中之一。有效三角形的规则用数组的方法来表达的话就是:nums[i] + nums[j] > nums[k],其中i,j,k是三个数组元素的下标,代表三条边。我们只要知道其中两条边,就能在剩余数组元素中得出符合这个规则的元素的数量,也就是有效三角形的数量。这里首先对数组排序,然后挑选i和j进行两层循环,在循环中用二分查找找到第一个不符合这个规则的下标k,因为数组是排过序的,所以在k之前的元素肯定都是符合要求的。对结果进行递增.最后返回结果
代码:
class Solution {
public:
int binarySearch(vector& nums, int l, int r, int target)
{
while (r >= l && r < nums.size())
{
int mid = (l+r)/2;
if (nums[mid] >= target)
{
r = mid-1;
}
else
{
l = mid+1;
}
}
return l;
}
int triangleNumber(vector& nums) {
if (nums.size() < 3)
{
return 0;
}
int res=0;
sort(nums.begin(), nums.end());
for (int i=0; i < nums.size()-2; i++)
{
int k = i+2;
for (int j = i+1; j < nums.size()-1 && nums[i] > 0; j++)
{
// find out where k is invalid
k = binarySearch(nums, k, nums.size()-1, nums[i]+nums[j]);
// res += valid range - 1 since we need to exclude k exactly
res += k-j-1;
}
}
return res;
}
};
时间复杂度:O(n^2logn) 排序需要logn时间复杂度,两层循环需要n^2时间复杂度。二分查找最坏情况是O(nlogn),循环n次
空间复杂度 :O(log(n))
另一种解法是双指针。和二分查找类似,枚举i和j然后增加k的位置直到k位置的元素不满足条件。增加结果为k-j-1。
代码:
class Solution {
public:
int triangleNumber(vector& nums) {
if (nums.size() < 3)
{
return 0;
}
int n = nums.size();
int res=0;
sort(nums.begin(), nums.end());
int k=0;
for (int i=0; i < n-2; i++)
{
k = i+2;
for (int j = i+1; j < n-1 && nums[i] > 0; j++)
{
// find out where is invalid
while (k < n && nums[i]+nums[j] > nums[k])
{
k++;
}
res += k-j-1;
}
}
return res;
}
};
时间复杂度:O(n^2)
空间复杂度:O(logn)
参考:
https://leetcode.com/problems/valid-triangle-number/
https://leetcode.com/problems/valid-triangle-number/solution/
https://leetcode-cn.com/problems/valid-triangle-number/
https://leetcode-cn.com/problems/valid-triangle-number/solution/you-xiao-san-jiao-xing-de-ge-shu-by-leetcode/