0% completed
Problem Statement
Given an array arr of unsorted numbers and a target sum, count all triplets in it such that arr[i] + arr[j] + arr[k] < target where i, j, and k are three different indices. Write a function to return the count of such triplets.
Example 1:
Input: [-1, 0, 2, 3], target=3
Output: 2
Explanation: There are two triplets whose sum is less than the target: [-1, 0, 3], [-1, 0, 2]
Example 2:
Input: [-1, 4, 2, 1, 3], target=5
Output: 4
Explanation: There are four triplets whose sum is less than the target:
[-1, 1, 4], [-1, 1, 3], [-1, 1, 2], [-1, 2, 3]
Constraints:
n == arr.length
0 <= n <= 3500
-100 <= arr[i] <= 100
-100 <= target <= 100
Solution
This problem follows the Two Pointers pattern and shares similarities with Triplet Sum to Zero. The only difference is that, in this problem, we need to find the triplets whose sum is less than the given target. To meet the condition i != j != k
we need to make sure that each number is not used more than once.
Following a similar approach, first, we can sort the array and then iterate through it, taking one number at a time. Let’s say during our iteration we are at number ‘X’, so we need to find ‘Y’ and ‘Z’ such that X + Y + Z < target. At this stage, our problem translates into finding a pair whose sum is less than “target - X” (as from the above equation Y + Z < target - X). We can use a similar approach as discussed in "Triplet Sum to Zero".
Here's a detailed walkthrough of the algorithm:
-
The method
searchTriplets
starts by sorting the input arrayarr
in ascending order. Sorting is important as it allows us to move our pointers based on the sum we are getting and how close we are to the target sum. -
The variable
count
is initialized to keep track of the total number of triplets found. -
The function then iterates through
arr
using afor
loop, stopping when it is two positions from the end ofarr
(arr.length - 2
). This is because we are always looking for triplets and thus don't need to consider the last two positions in this loop. -
Inside the
for
loop, we call thesearchPair
function with the array, the target value minus the current element, and the current index. This function will find all pairs within the array from indexfirst+1
to the end of the array whose sum witharr[i]
is less thantarget
. The return value, which is the count of such pairs, is added tocount
. -
The
searchPair
function initializes two pointers:left
tofirst+1
andright
to the last element in the array. It then enters awhile
loop that continues as long asleft
is less thanright
. -
In the loop, if the sum of the elements at the
left
andright
indices is less thantargetSum
, this means we have found a valid pair, because addingarr[first]
would still result in a sum less thantarget
. Since the array is sorted, all the elements betweenleft
andright
witharr[first]
will also form valid triplets. So, we add all these pairs to ourcount
by addingright - left
tocount
. -
We then increment
left
to move towards higher numbers in the array. -
If the sum of the elements at
left
andright
is not less thantargetSum
, we need a smaller sum. Since the array is sorted, to achieve a smaller sum, we need to reduce the value of the larger number. Hence, we decrementright
. -
This process repeats until
left
andright
cross, at which point we have examined all possible pairs for our current value offirst
. -
Once
searchPair
has processed all possible pairs for the givenfirst
index, it returns thecount
of valid pairs. -
The loop in
searchTriplets
continues until we have tried every possible starting point for our triplet. -
Once all possible triplets have been considered, the
searchTriplets
function returnscount
, the total number of triplets whose sum is less thantarget
.
Algorithm Walkthrough
Let's use the input arr = [-1, 4, 2, 1, 3]
and target = 5
.
-
Sort the Array:
- Sorted array:
[-1, 1, 2, 3, 4]
- Sorted array:
-
Initialize Counter:
count = 0
-
Loop Through the Array:
- i = 0, fixed element is
-1
:- Target sum for pairs:
5 - (-1) = 6
- Initialize pointers:
left = 1
,right = 4
- Target sum for pairs:
- i = 0, fixed element is
-
Search for Pairs:
- While left < right:
sum = arr[1] + arr[4] = 1 + 4 = 5
(less than 6)- Add
right - left = 4 - 1 = 3
tocount
, moveleft
to2
- Add
sum = arr[2] + arr[4] = 2 + 4 = 6
(not less than 6), moveright
to3
sum = arr[2] + arr[3] = 2 + 3 = 5
(less than 6)- Add
right - left = 3 - 2 = 1
tocount
, moveleft
to3
- Add
- End of while loop:
count = 4
- While left < right:
-
Next Iteration:
- i = 1, fixed element is
1
:- Target sum for pairs:
5 - 1 = 4
- Initialize pointers:
left = 2
,right = 4
- Target sum for pairs:
- While left < right:
sum = arr[2] + arr[4] = 2 + 4 = 6
(not less than 4), moveright
to3
sum = arr[2] + arr[3] = 2 + 3 = 5
(not less than 4), moveright
to2
- End of while loop:
count = 4
- i = 1, fixed element is
-
Next Iteration:
- i = 2, fixed element is
2
:- Target sum for pairs:
5 - 2 = 3
- Initialize pointers:
left = 3
,right = 4
- Target sum for pairs:
- While left < right:
sum = arr[3] + arr[4] = 3 + 4 = 7
(not less than 3), moveright
to3
- End of while loop:
count = 4
- i = 2, fixed element is
-
Final Count:
- Return
count = 4
- Return
Let's visualize the example 2 via diagram below.
Code
Here is what our algorithm will look like:
Complexity Analysis
Time Complexity
-
Sorting the array: The algorithm first sorts the input array, which takes O(N \log N), where
N
is the number of elements in the array. -
Outer loop: The main loop iterates from index 0 to
N-3
, which is O(N). -
Two-pointer search (searchPair): For each iteration of the outer loop, the algorithm performs a two-pointer search, which operates in O(N) time. This search finds all pairs whose sum is less than the
targetSum
(for the current element).
Overall time complexity: The total time complexity is O(N \log N + N^2). Since N^2 dominates N \log N, the overall time complexity is O(N^2).
Space Complexity
-
Sorting the array: The sorting operation requires extra space which takes an additional O(N) space complexity.
-
Constant extra space: Apart from sorting, the algorithm uses a constant amount of extra space for variables like
count
,left
, andright
, which take up O(1) space.
Overall space complexity: The total space complexity is O(N) due to the space required for sorting.
Similar Problems
Problem:
Write a function to return the list of all such triplets instead of the count. How will the time complexity change in this case?
Solution:
Following a similar approach, we can create a list containing all the triplets. Here is the code::
Another simpler approach could be to check every triplet of the array with three nested loops and create a list of triplets that meet the required condition.
Complexity Analysis
Time Complexity
-
Sorting the array: The first step of the algorithm is sorting the input array, which takes O(N \log N), where
N
is the number of elements in the array. -
Outer loop: The outer loop runs from index 0 to
N-3
, which takes O(N) time. -
Inner two-pointer search (searchPair): For each element in the outer loop, the two-pointer search runs. In the worst case, the two-pointer technique checks all elements between
left
andright
, and for each pair, it iterates over the range fromright
toleft+1
to add valid triplets. This adds additional iterations within the inner loop, making the inner loop take O(N) in the worst case. -
Adding triplets: For each valid triplet found, the algorithm iterates over all possible pairs between
left
andright
, which takes O(N) time.
Overall time complexity: The time complexity for each iteration of the outer loop is O(N^2) because for each element, the two-pointer search takes O(N), and adding valid triplets takes another O(N). As a result, the overall time complexity is O(N^3).
Space Complexity
-
Sorting the array: If the sorting operation requires additional space (such as merge sort), it adds O(N) space complexity.
-
Triplets storage: The algorithm stores all unique triplets in the
triplets
list. In the worst case, the algorithm can store up to O(N^3) triplets if many valid triplet combinations are found. -
Extra variables: The algorithm uses a few extra variables (
left
,right
, andfirst
), all of which take constant space O(1).
Overall space complexity: O(N^3) for storing the triplets and O(N) for sorting, resulting in O(N^3) total space complexity.
.....
.....
.....
Table of Contents
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible