題目:
這道題我們首先可能會想到暴力解法,三個for循環然后進行check()。時間復雜度肯定是不允許的。
同時,驗證可以組成三角形的條件是任意兩邊之和大于第三邊,這就意味著我們每組要進行三次比較。但也有捷徑——只需比較一次即可。但需要條件,讓這三個數的組合按從小到大進行排列(a≤b≤c),然后我們只需驗證a+b是否大于c即可。因此第一步,我們要把數組進行排序(sort)。
然后我們接下來的思路與雙指針(4)的原理有點類似:
我們先計算arr[left]+arr[right](1+9=10,不構成),如果滿足a+b≤c,那么left和right的中間任何一個數和left組合都不能滿足三角形,所以此時我們就可以把所有數與left的組合都忽略(不用計算了)即,讓left++,這是一次流程。反之如果大于c,那么此次流程中的所有數與right結合都滿足要求,則有效三角形個數為right-left,然后讓right--進行下一次流程,直到left與right相遇。
注意:以上整個流程都是在與10比較,當二者相遇為一個循環,循環結束后,我們要讓二者與9(往前一個)比較。直到走到第三個為止。統計每次循環的有效數并求和。
int Solution(vector<int>& nums)
{sort(nums.begin(),nums.end());int ret=0, n=nums.size();for(int i=n-1;i>=2;i--){int left=0,right=i-1;while(left<right){if(nums[left]+nums[right]>nums[i]){ret+=right-left;right--;}else left++;}}return ret;}