0% completed
Problem Statement
Given an array of unsorted numbers and a target number, find all unique quadruplets in it, whose sum is equal to the target number.
Example 1:
Input: [4, 1, 2, -1, 1, -3], target=1
Output: [-3, -1, 1, 4], [-3, 1, 1, 2]
Explanation: Both the quadruplets add up to the target.
Example 2:
Input: [2, 0, -1, 1, -2, 2], target=2
Output: [-2, 0, 2, 2], [-1, 0, 1, 2]
Explanation: Both the quadruplets add up to the target.
Constraints:
1 <= nums.length <= 200
- -10<sup>9</sup> <= nums[i] <= 10<sup>9</sup>
- -10<sup>9</sup> <= target <= 10<sup>9</sup>
Solution
This problem follows the Two Pointers pattern and shares similarities with "Triplet Sum to Zero".
We can follow a similar approach to iterate through the array, taking one number at a time. At every step during the iteration, we will search for the quadruplets similar to Triplet Sum to Zero whose sum is equal to the given target.
Here's a detailed walkthrough of the algorithm:
-
In
searchQuadruplets
, the array is first sorted in ascending order. Sorting is important as it allows us to navigate our pointers based on the sum we're calculating and ensures that the generated quadruplets are in a predictable order. -
A
List
namedquadruplets
is created to store all the quadruplets found. -
The algorithm then loops over the array, stopping when there are less than four elements remaining (since we need groups of four).
-
If the current element is the same as the previous one (and it's not the first), we skip this iteration to avoid duplicate quadruplets.
-
A nested loop is initiated from the next index of the outer loop. This loop also ensures that the current element isn't the same as the previous one to avoid duplicates.
-
The
searchPairs
function is called with the array, target value, indices of the first two elements, and thequadruplets
list. This function will find pairs in the array (fromsecond+1
index to the end) whose sum witharr[first]
andarr[second]
equals the target. Any valid quadruplets found are added to thequadruplets
list. -
In
searchPairs
, two pointersleft
andright
are initialized:left
tosecond+1
, andright
to the last element of the array. It then enters a while loop that continues untilleft
is less thanright
. -
Inside this loop, the sum of the elements at the current four indices (
first
,second
,left
,right
) is calculated. If this sum equalstargetSum
, a valid quadruplet is found. -
This quadruplet is added to the
quadruplets
list, and bothleft
andright
pointers are moved inward. If the next elements are the same as the current elements ofleft
andright
respectively, they are skipped to avoid duplicates. -
If the calculated sum is less than
targetSum
,left
is incremented to increase the sum (as the array is sorted), and if the sum is greater thantargetSum
,right
is decremented to decrease the sum. -
This process repeats until
left
andright
cross, by which point all possible pairs for the givenfirst
andsecond
indices have been examined. -
Once
searchPairs
has processed all possible pairs for the givenfirst
andsecond
indices, it returns, and the nested loop insearchQuadruplets
continues until all possible starting points for quadruplets have been tried. -
Once all possible quadruplets have been considered,
searchQuadruplets
returns thequadruplets
list.
The main
function in the code demonstrates usage of the searchQuadruplets
function with two test cases. It runs searchQuadruplets
with specified arrays and target sums, printing the results to the console.
Algorithm Walkthrough
Let's walk through the algorithm using the example input [4, 1, 2, -1, 1, -3]
with a target of 1
.
-
Sort the Array:
- Input:
[4, 1, 2, -1, 1, -3]
- Sorted Array:
[-3, -1, 1, 1, 2, 4]
- Input:
-
Initialize Result List:
quadruplets = []
-
First Loop (
i = 0
):- Current Element (
arr[i] = -3
) - Second Loop (
j = 1
):- Current Element (
arr[j] = -1
) - Two Pointers:
left = 2
,right = 5
- Current Element (
- Current Element (
-
Two-Pointer Process:
- First Sum Calculation:
sum = arr[0] + arr[1] + arr[2] + arr[5]
sum = -3 + (-1) + 1 + 4 = 1
- Matches Target: Add
[-3, -1, 1, 4]
toquadruplets
- Update Pointers:
left = 3
right = 4
- Check Duplicates:
- Skip duplicates by moving pointers:
left
moves to4
right
moves to4
- Skip duplicates by moving pointers:
- Second Sum Calculation:
- Pointers Overlap: End of this pair search
- First Sum Calculation:
-
Second Loop (
j = 2
):- Current Element (
arr[j] = 1
) - Two Pointers:
left = 3
,right = 5
- First Sum Calculation:
sum = arr[0] + arr[2] + arr[3] + arr[5]
sum = -3 + 1 + 1 + 4 = 3
- Greater Than Target: Move
right
pointer leftright = 4
- Second Sum Calculation:
sum = arr[0] + arr[2] + arr[3] + arr[4]
sum = -3 + 1 + 1 + 2 = 1
- Matches Target: Add
[-3, 1, 1, 2]
toquadruplets
- Update Pointers:
left = 4
right = 3
- Check Duplicates:
- Skip duplicates by moving pointers:
left
moves to4
right
moves to3
- Skip duplicates by moving pointers:
- Pointers Overlap: End of this pair search
- Current Element (
-
Second Loop (
j = 3
):- Current Element (
arr[j] = 1
) (Duplicate) - Skip this element to avoid duplicates.
- Current Element (
-
First Loop (
i = 1
):- Current Element (
arr[i] = -1
) - Second Loop (
j = 2
):- Current Element (
arr[j] = 1
) - Two Pointers:
left = 3
,right = 5
- Current Element (
- First Sum Calculation:
sum = arr[1] + arr[2] + arr[3] + arr[5]
sum = -1 + 1 + 1 + 4 = 5
- Greater Than Target: Move
right
pointer leftright = 4
- Second Sum Calculation:
sum = arr[1] + arr[2] + arr[3] + arr[4]
sum = -1 + 1 + 1 + 2 = 3
- Greater Than Target: Move
right
pointer leftright = 3
- Pointers Overlap: End of this pair search
- Current Element (
-
Second Loop (
j = 3
):- Current Element (
arr[j] = 1
) (Duplicate) - Skip this element to avoid duplicates.
- Current Element (
-
First Loop (
i = 2
):- Current Element (
arr[i] = 1
) - Second Loop (
j = 3
):- Current Element (
arr[j] = 1
) (Duplicate)
- Current Element (
- Skip this element to avoid duplicates.
- Current Element (
- Final Result: The unique quadruplets are
[[ -3, -1, 1, 4], [-3, 1, 1, 2]]
.
Let's walkthrough the example 1 through diagram below.
Code
Here is what our algorithm will look like:
Complexity Analysis
Time Complexity
-
Sorting the array: The algorithm begins by sorting the input array, which takes O(N \log N), where
N
is the number of elements in the array. -
Outer loop (i): The first loop runs from
i = 0
toi = N-4
(i.e., up to the fourth-to-last element in the array). This loop runs O(N) times. -
Second loop (j): The second loop runs from
j = i + 1
toj = N-3
(i.e., up to the third-to-last element in the array). This loop also runs O(N) times for each iteration of the first loop. -
Two-pointer search (left and right): For each iteration of the second loop, the two-pointer technique is used to find the remaining two numbers. The two-pointer search takes O(N) time in the worst case.
Overall time complexity: The total time complexity is O(NlogN + N^3) \approx O(N^3) because we have three nested loops and each one runs in linear time. Thus, the overall time complexity is O(N^3).
Space Complexity
-
Sorting the array: Sorting requires additional space which is uses O(N).
-
Resultant quadruplets storage: The algorithm uses a list
quadruplets
to store the resulting quadruplets. In the worst case, there can be O(N^3) quadruplets if many valid quadruplets are found. -
Auxiliary space: A few additional variables (
i
,j
,left
,right
, etc.) are used, which require constant space O(1).
Overall space complexity: The space complexity for storing the result is O(K), where K
is the number of quadruplets, and K can be as large as O(N^3). Adding the space for sorting, the total space complexity becomes O(N^3) in the worst case.
.....
.....
.....
Table of Contents
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible