文章目录
- 一【题目类别】
- 二【题目难度】
- 三【题目编号】
- 四【题目描述】
- 五【题目示例】
- 六【解题思路】
- 七【题目提示】
- 八【时间频度】
- 九【代码实现】
- 十【提交结果】
一【题目类别】
- 二分查找
二【题目难度】
- 中等
三【题目编号】
- 611.有效三角形的个数
四【题目描述】
- 给定一个包含非负整数的数组 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
六【解题思路】
- 对于如何组成合法三角形,从小学我们就学过了:任意两边之和大于第三边。所以基于这个思路,我们只需要在数组中逐个判断任意两边之和是否大于第三边
- 找到前两边比较简单,遍历即可,那么如何找到第三边呢?如果也通过遍历去寻找,很明显时间复杂度是 O ( n 3 ) O(n^3) O(n3),为了降低时间复杂度,我们可以使用二分查找来找到第三边,既然使用二分查找,就要首先对数组进行排序
- 然后需要找到前两边,这个使用 f o r for for循环遍历即可
- 找第三边的时候使用二分查找,我们只需要将中间值对应的边长和其余两边之和比较,如果中间值对应的边长大于或等于其余两边之和,这显然是不满足的,那么应该继续向左查找,因为左边的值比较小;反之应该向右查找,因为数组现在是有序的,中间值满足要求,那么小于中间值的也都满足要求,记录这个位置,并向右查找是否还有满足要求的值
- 每次遍历将得到的结果累加记录,需要注意上一步记录位置的变量需要初始化为第二条边的位置,因为最后算个数的时候,没有满足要求的边就不会累加,否则会出错
- 最后返回结果即可
七【题目提示】
- 1 < = n u m s . l e n g t h < = 1000 1 <= nums.length <= 1000 1<=nums.length<=1000
- 0 < = n u m s [ i ] < = 1000 0 <= nums[i] <= 1000 0<=nums[i]<=1000
八【时间频度】
- 时间复杂度: O ( n 2 l o g n ) O(n^2logn) O(n2logn),其中 n n n为数组的长度
- 空间复杂度: O ( l o g n ) O(logn) O(logn),其中 n n n为数组的长度
九【代码实现】
- Java语言版
class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int len = nums.length;
int res = 0;
for(int i = 0;i<len;i++){
for(int j = i + 1;j<len;j++){
int left = j + 1;
int right = len - 1;
int k = j;
while(left <= right){
int mid = (left + right) / 2;
if(nums[mid] >= nums[i] + nums[j]){
right = mid - 1;
}else{
k = mid;
left = mid + 1;
}
}
res += k - j;
}
}
return res;
}
}
- C语言版
int compare(int *a,int *b)
{
return *a - *b;
}
int triangleNumber(int* nums, int numsSize)
{
qsort(nums,numsSize,sizeof(int),compare);
int len = numsSize;
int res = 0;
for(int i = 0;i<len;i++)
{
for(int j = i + 1;j<len;j++)
{
int left = j + 1;
int right = len - 1;
int k = j;
while(left <= right)
{
int mid = (left + right) / 2;
if(nums[mid] >= nums[i] + nums[j])
{
right = mid - 1;
}
else
{
k = mid;
left = mid + 1;
}
}
res += k - j;
}
}
return res;
}
- Python版
class Solution:
def triangleNumber(self, nums: List[int]) -> int:
nums.sort()
n = len(nums)
res = 0
for i in range(0,n):
for j in range(i + 1,n):
left = j + 1
right = n - 1
k = j
while left <= right:
mid = (left + right) // 2
if nums[mid] >= nums[i] + nums[j]:
right = mid - 1
else:
k = mid
left = mid + 1
res += k - j
return res
十【提交结果】
-
Java语言版
-
C语言版
-
Python语言版