topic
Given an array nums containing non-negative integers, return the number of triples that can form three sides of a triangle.
Example 1:
Input: nums = [2,2,3,4]
Output: 3
Explanation: Valid combinations are:
2,3,4 (use the first 2)
2,3,4 (use the second 2)
2,2 ,3
Example 2:
Input: nums = [4,2,3,4]
Output: 4
hint:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
answer
Sorting + Binary Search
The triangle must satisfy a+b>c; a+c>b; b+c>a.
After sorting, a+c>b and b+c>a must be satisfied, just look for a+b> c
class Solution {
public:
int triangleNumber(vector<int>& nums) {
int len = nums.size();
if(len<3)
return 0;
sort(nums.begin(),nums.end());
int result = 0;
for(int i=0;i<len-2;i++)
{
for(int j=i+1;j<len-1;j++)
{
int left = j+1;
int right = len-1;
int target = nums[i]+nums[j];
while(left<=right)
{
int mid = (left+right)>>1;
if(nums[mid]<target)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
result+= right-j ;
}
}
return result;
}
};
Sorting + double pointers
are violent optimizations.
The violent method is three loops, resetting k each time and looping.
But in the sorted sequence, because it is increasing, a+b is also increasing, that is to say, for each For example, you don’t need to reset k every time to traverse, you just need to continue going backwards from the last time.
class Solution {
public:
int triangleNumber(vector<int>& nums) {
int len = nums.size();
if(len<3)
return 0;
sort(nums.begin(),nums.end());
int result = 0;
for(int i=0;i<len-2;i++)
{
int k = i+1;
for(int j=i+1;j<len-1;j++)
{
int target = nums[i] + nums[j];
while(k+1<len && nums[k+1]<target)
k++;
result += max(k-j,0);
}
}
return result;
}
};