Leetcode 18: 4Sum
You are given an array of integers
nums
and a target value. Your task is to find all unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that the sum of the four numbers equals the target value. The indices a, b, c, and d should be distinct.Problem
Approach
Steps
Complexity
Input: The input consists of an integer array `nums` of size `n`, and an integer `target` representing the target sum.
Example: Input: nums = [-3, 0, 1, 2, -1, -4], target = 0
Constraints:
• 1 <= nums.length <= 200
• -10^9 <= nums[i] <= 10^9
• -10^9 <= target <= 10^9
Output: Return a 2D array of all unique quadruplets that sum up to the given target.
Example: Output: [[-3, -1, 1, 2], [-4, 0, 1, 2]]
Constraints:
• The quadruplets should be unique, and the answer can be returned in any order.
Goal: To find all unique quadruplets whose sum is equal to the target value.
Steps:
• 1. Sort the input array to enable efficient two-pointer traversal.
• 2. Use two nested loops to fix the first two elements of the quadruplet.
• 3. Use two pointers to find the remaining two elements that together sum to the remaining target.
Goal: The solution needs to handle arrays of various sizes and values efficiently.
Steps:
• The length of the array is between 1 and 200.
• Elements can range from -10^9 to 10^9.
Assumptions:
• The array will have at least 4 elements to form a quadruplet.
• Input: Input: nums = [-3, 0, 1, 2, -1, -4], target = 0
• Explanation: The unique quadruplets that sum to 0 are: [-3, -1, 1, 2] and [-4, 0, 1, 2].
• Input: Input: nums = [2, 2, 2, 2, 2], target = 8
• Explanation: The only unique quadruplet that sums to 8 is [2, 2, 2, 2].
Approach: To solve this problem, we can use sorting and the two-pointer technique to efficiently find unique quadruplets that sum to the target.
Observations:
• The two-pointer technique helps to find pairs of numbers efficiently once two elements are fixed.
• Sorting the array allows us to avoid duplicates by skipping repeated elements.
• By sorting the array and using two nested loops to fix the first two numbers, we can use two pointers to find the other two numbers that sum up to the remaining target.
Steps:
• 1. Sort the input array.
• 2. Iterate through the array with two nested loops to fix the first two elements of the quadruplet.
• 3. For each pair of fixed elements, use two pointers (low and high) to find the other two elements that sum to the remaining target.
• 4. Add each valid quadruplet to a set to ensure uniqueness.
• 5. Return the set as a list of quadruplets.
Empty Inputs:
• If the array has fewer than 4 elements, it's impossible to form a quadruplet, so the result should be an empty list.
Large Inputs:
• If the array has many elements, the solution should be optimized to handle large input sizes efficiently.
Special Values:
• If all elements in the array are the same, only one unique quadruplet should be returned.
Constraints:
• Ensure that the solution works within the time and space complexity limits, especially when handling larger inputs.
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
sort(nums.begin(), nums.end());
set<vector<int>> set;
vector<vector<int>> output;
for(int i=0; i<n-3; i++){
for(int j=i+1; j<n-2; j++){
long long newTarget = (long long)target - (long long)nums[i] - (long long)nums[j];
int low = j+1, high = n-1;
while(low < high){
if(nums[low] + nums[high] < newTarget){
low++;
}
else if(nums[low] + nums[high] > newTarget){
high--;
}
else{
set.insert({nums[i], nums[j], nums[low], nums[high]});
low++; high--;
}
}
}
}
for(auto it : set){
output.push_back(it);
}
return output;
}
1 : Function Declaration
vector<vector<int>> fourSum(vector<int>& nums, int target) {
Declare the `fourSum` function, which takes a vector of integers `nums` and a target integer `target` as input and returns a vector of vectors representing the unique quadruplets.
2 : Variable Initialization
int n = nums.size();
Store the size of the `nums` vector in `n` for efficient indexing.
3 : Sorting Operations
sort(nums.begin(), nums.end());
Sort the `nums` vector in ascending order to facilitate the two-pointer approach.
4 : Set Initialization
set<vector<int>> set;
Initialize a set `set` to store unique quadruplets to avoid duplicates.
5 : Variable Initialization
vector<vector<int>> output;
Initialize a vector `output` to store the final result of unique quadruplets.
6 : Nested Loops
for(int i=0; i<n-3; i++){
Start the first outer loop to iterate over the first element of the quadruplet.
7 : Nested Loops
for(int j=i+1; j<n-2; j++){
Start the second outer loop to iterate over the second element of the quadruplet, ensuring `j` is greater than `i` to avoid duplicates.
8 : Calculations
long long newTarget = (long long)target - (long long)nums[i] - (long long)nums[j];
Calculate the target sum for the remaining two numbers: `newTarget = target - nums[i] - nums[j]`. Cast to `long long` to avoid integer overflow.
9 : Variable Initialization
int low = j+1, high = n-1;
Initialize two pointers `low` and `high` to start the two-pointer approach for the remaining two elements.
10 : Loop Iteration
while(low < high){
Start the two-pointer loop to find pairs that add up to `newTarget`.
11 : Conditional Update
if(nums[low] + nums[high] < newTarget){
low++;
}
If the sum of `nums[low]` and `nums[high]` is less than `newTarget`, move `low` to the right to increase the sum.
12 : Conditional Update
else if(nums[low] + nums[high] > newTarget){
high--;
}
If the sum of `nums[low]` and `nums[high]` is greater than `newTarget`, move `high` to the left to decrease the sum.
13 : Set Operations
else{
set.insert({nums[i], nums[j], nums[low], nums[high]});
low++; high--;
}
If the sum is equal to `newTarget`, insert the quadruplet into the `set` to avoid duplicates and move both pointers to find other potential quadruplets.
14 : Set Iteration
for(auto it : set){
Iterate through the unique quadruplets in the `set`.
15 : Array Manipulation
output.push_back(it);
Add each unique quadruplet to the `output` vector.
16 : Return Value
return output;
Return the `output` vector containing all unique quadruplets.
Best Case: O(n^3), where `n` is the length of the array. This occurs when no early exits happen.
Average Case: O(n^3), as the solution involves three nested loops and two pointers.
Worst Case: O(n^3), since the worst case happens when the algorithm must iterate over most combinations of elements.
Description: The time complexity is cubic in the length of the array due to the three loops and the two-pointer technique.
Best Case: O(n), as the space used by the set is dependent on the number of unique quadruplets.
Worst Case: O(n), where `n` is the number of unique quadruplets. This is the space used by the set to store unique quadruplets.
Description: The space complexity depends on the number of unique quadruplets stored in the result set.
LeetCode Solutions Library / DSA Sheets / Course Catalog |
---|
comments powered by Disqus