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
The problem asks to find the number of triplets in an array nums
that can form the sides of a triangle. A triangle is valid if the sum of the lengths of any two sides is greater than the length of the third side.
Approach:
The most efficient approach involves sorting the array and then using a two-pointer technique or binary search for each pair of potential sides. Here's a breakdown:
Sorting: First, sort the input array nums
in ascending order. This is crucial for efficiently finding valid triplets. Sorting takes O(n log n) time.
Iterating Through Potential Sides: Iterate through the array using a nested loop. The outer loop iterates from i = 0
to n - 3
(where n
is the length of nums
). The inner loop iterates from j = i + 1
to n - 2
. Each pair (nums[i], nums[j])
represents two potential sides of a triangle.
Finding the Third Side (Two-Pointer or Binary Search): For each pair (nums[i], nums[j])
, we need to find how many numbers in the array are greater than nums[i] + nums[j]
and are also greater than nums[j]
(to ensure the third side is larger than the second side and obeys the triangle inequality). There are two methods to achieve this efficiently:
Two-Pointer Approach: This method is faster. Use a left
pointer starting at j + 1
and a right
pointer at n - 1
. Move the pointers until the condition nums[left] + nums[j] > nums[i]
is satisfied. The number of valid triangles is then given by right - left
. This approach has a time complexity of O(n) for the inner loop and O(n^2) for the outer loops.
Binary Search Approach: We can use binary search to find the largest index k
such that nums[k] < nums[i] + nums[j]
. This binary search takes O(log n) time. The number of valid triangles for this pair is then k - j
. This approach has a time complexity of O(n^2 log n).
Time Complexity Analysis:
Therefore, the overall time complexity of the solution using the two-pointer approach is O(n^2), dominated by the nested loops. The solution using binary search is O(n^2 log n). The space complexity is O(1) (constant) because we're only using a few extra variables, not dependent on the input size.
Space Complexity Analysis: O(1)
Code Examples (Two-Pointer Approach):
The provided Java, C++, Go, and TypeScript solutions all use the two-pointer approach, which is more efficient than binary search in this case. The Python solution uses bisect_left
which is essentially a binary search, leading to slightly higher time complexity.
This detailed explanation, including complexity analysis and code examples in multiple languages, gives a comprehensive understanding of how to solve the Valid Triangle Number problem efficiently. The two-pointer approach is generally preferred for its better time complexity in this scenario.