一共四种组成三角形的方式:
1,等边三角形,要求相同边至少有3条
2,等腰三角形,分为钝角等腰,要求两短边之和大于第三边,另一个为锐角等腰,要求长边数量大于2
3,普通三角形,利用前缀和来加速计算,快速计算出满足High - Low 差值之间的边的数量
/*
* @lc app=leetcode id=611 lang=cpp
*
* [611] Valid Triangle Number
*/
// @lc code=start
class Solution {
public:
int triangleNumber(vector<int>& nums) {
int N = nums.size();
if(N < 3) {
return 0;
}
const int MAXN = 1001;
int mp[MAXN];
int sum[MAXN];
memset(mp,0,sizeof(mp));
memset(sum,0,sizeof(sum));
for(int i=0;i<N;i++){
mp[nums[i]]++;
}
for(int i=1;i<MAXN;i++){
sum[i] += sum[i-1] + mp[i];
}
int ans = 0;
for(int i=1;i<MAXN;i++){
if(mp[i] == 0) continue;
ans += getSame3(mp[i]);
for(int j=i+1;j<MAXN;j++){
if(mp[j] == 0) continue;
// 关键,max(i,j-i),找出i和j之间,满足大于差值j-i的边数量
ans += getSame1(mp[j], mp[i], sum[j-1] - sum[max(i,j-i)]);
if(j < i*2) ans += getSame2low(mp[j], mp[i]);
if(mp[j] > 1 ) ans += getSame2high(mp[j], mp[i]);
}
}
return ans;
}
int getSame3(int cnt) {
if(cnt < 3) return 0;
return cnt*(cnt-1)*(cnt-2)/6;
}
int getSame2low(int high, int low) {
return low * (low-1) * high / 2 ;
}
int getSame2high(int high, int low) {
return high * (high-1) * low / 2 ;
}
int getSame1(int high, int low, int mid){
return high * low * mid ;
}
};
// @lc code=end