Given an array consists of non-negative integers, your task is to count the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle.
Example 1:
Input: [2,2,3,4]
Output: 3
Explanation:
Valid combinations are:
2,3,4 (using the first 2)
2,3,4 (using the second 2)
2,2,3
Note:
The length of the given array won't exceed 1000.
The integers in the given array are in the range of [0, 1000].
Solutions
My solutions
Solution 1
classSolution {public:inttriangleNumber(vector<int>& nums) {sort(nums.begin(),nums.end());int count =0, n =nums.size();for(int i =0; i +2< n; ++i){for(int j = i +1; j +1< n; ++j){int k = j +1;while(k < n &&nums[k] <nums[i] +nums[j]) ++k; count += k - j -1; } }return count; }};
Solution 2
classSolution {public:inttriangleNumber(vector<int>& nums) {sort(nums.begin(),nums.end());int count =0, n =nums.size();int i =0;while(i < n &&nums[i] ==0) ++i;for( ; i +2< n; ++i){int k = i +2;for(int j = i +1; j +1< n; ++j){while(k < n &&nums[k] <nums[i] +nums[j]) ++k; count += k - j -1; } }return count; }};
A better solution
The previous solutions fix two shorter sides. This solution fixes the longest side and then use binary search to find the other two sides.
classSolution {public:inttriangleNumber(vector<int>& nums) {int count =0;int n =nums.size();sort(nums.begin(),nums.end());for(int i = n -1; i >=2; --i){int l =0, r = i -1;while(l < r){if(nums[l] +nums[r] >nums[i]){ count += r - l;--r; }else{++l; } } }return count; }};