Description

Given an integer array nums, return 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: nums = [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

Example 2:

Input: nums = [4,2,3,4] Output: 4

Constraints:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000

Code

Two Pointer

固定最大的那個邊,這題就變成 3Sum 類似的題目。

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n = nums.size(), ans = 0;
        for (int k = 2; k < n; ++k) {
            int i = 0, j = k - 1;
            while (i < j) {
                if (nums[i] + nums[j] > nums[k]) {
                    ans += j - i;
                    j -= 1;
                } else {
                    i += 1;
                }
            }
        }
        return ans;
    }
};

Time Complexity: , Space Complexity:

[2, 3, 4, 4] 為例,當 a, b 分別為 2, 3 時,4, 4 都是解,因此要加上 (int)(iter - (nums.begin() + j + 1),也就是從 end 減第一個 4 的位置,剛好就是 4 的數量。

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        int count = 0, n = nums.size();
        sort(nums.begin(), nums.end());
        /*
        a + b > c
        prev(>= a + b) -> < a + b, which is c
        */
 
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
                int ab = nums[i] + nums[j];
                auto iter = lower_bound(nums.begin() + j + 1, nums.end(), ab);
                count += max((int)(iter - (nums.begin() + j + 1)), 0);
            }
        }
        
        return count;
    }
};

Source