给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。
输入: [2,2,3,4]
输出: 3
解释:
有效的组合是:
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3
数组长度不超过1000。
数组里整数的范围为 [0, 1000]。
class Solution {
public://先枚举最大数,再往下枚举次大数,保证不重复
void qsort(vector<int>&a,int l,int r){
int i=l,j=r,flag=a[l+(r-l)/2];
do{
while(a[i]<flag)i++;
while(a[j]>flag)j--;
if(i<=j)swap(a[i++],a[j--]);
}while(i<=j);
if(l<j)qsort(a,l,j);
if(i<r)qsort(a,i,r);
}
int triangleNumber(vector<int>& nums) {
int jie=0;
int n=nums.size();
qsort(nums,0,n-1);
for(int i=0;i<n;i++){
for(int j=i-1;j>=0;j--){
for(int k=j-1;k>=0;k--)
if(nums[i]<nums[j]+nums[k])jie++;
}
}
return jie;
}
};
class Solution {
public:
void qsort(vector<int>&a,int l,int r){//快排模板之一
int i=l,j=r,flag=a[l+(r-l)/2];
do{
while(a[i]<flag)i++;
while(a[j]>flag)j--;
if(i<=j)swap(a[i++],a[j--]);
}while(i<=j);
if(l<j)qsort(a,l,j);
if(i<r)qsort(a,i,r);
}
int triangleNumber(vector<int>& nums) {
int n=nums.size();
qsort(nums,0,n-1);
int jie=0;
for(int i=0;i<n-2;++i){//二重循环,枚举a,b两小边
for(int j=i+1;j<n-1;++j){//在[j+1,n-1]处二分查找c的最大位置
int left=j+1,right=n-1,k=j;
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]<nums[i]+nums[j]){
k=mid;
left=mid+1;
}
else right=mid-1;
}
jie+=k-j; //加上c和b的间隔即可
}
}
return jie;
}
};
NTT快速卷积解法
(找时间完善ing,X﹏X,那个NTT快速卷积太秒了)