
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
4Sum in C++
4SUM Problem
The 4Sum is one of the problem variations in which we need to find the number of quadruplets present in the array such that their sum is equal to the given target.
We are given an array of n integers called nums and a target value, and we have to find the number of index quadruplets (i, j, k, l) where i, j, k, and l are all indices in the range 0 to n - 1, such that they satisfy the condition:
nums[i] + nums[j] + nums[k] + nums[l] = target
Scenario 1
Inputs: arr= [-1,0,1,2,0,-2], target= 0 Output: [[-1, 0, 0, 1],[-2, -1, 1, 2], [-2, 0, 0, 2]] Explanation In this, the value of the given target is 0; therefore, we can find that there are three possible quadruplets from a given array, whose sum is equal to 0. That's [-1, 0, 0, 1],[-2, -1, 1, 2], and [-2, 0, 0, 2].
Scenario 2
Inputs: arr= [1, 2, 3, 4, 5, 6, 7], target= 12 Output: [[1, 2, 3, 6], [1, 2, 4, 5]] Explanation In this, the value of the given target is 12; therefore, we can find that there are two possible quadruplets from a given array, whose sum is equal to 12. That's [1, 2, 3, 6] and [1, 2, 4, 5].
In this article, we will learn three different methods to solve the given problem of 4Sum in C++.
- Using Nested Loops (Brute Force Approach)
- Using Hashing(Better Approach)
- Using Two Pointers(Optimal Approach)
Solving 4Sum Using Nested Loops
When a loop is created inside another loop, forming multiple levels of loops, then it is said to be a nested loop.
Here, we will use four nested for loops to fix each element of the quadruplets one by one, and will check all possible combinations, and for every combination we will calculate the sum and compare it with a given target.
Algorithm
Here is the following algorithm we will follow to solve our given problem using nested loops in C++.
- First, initialize a set <vector<int>> to store unique quadruplets.
- Fix the first element using a for loop with index i from 0 to n - 4.
- Inside that loop, fix the second element using another loop with index j from i + 1 to n - 3.
- Fix the third element using a third loop with index k from j + 1 to n - 2.
- At last, fix the fourth element using a fourth loop with index l from k + 1 to n - 1.
- For each quadruplet (nums[i], nums[j], nums[k], nums[l]), check if the sum is equal to the given target.
- If true, sort it and insert it into the set to keep only distinct combinations.
Example
Here is an example code that uses nested loops to solve the 4Sum in C++.
#include <bits/stdc++.h> using namespace std; vector<vector<int>> fourSum(vector<int>& nums, int target) { int n = nums.size(); //size of the array set<vector<int>> st; //checking all possible quadruplets: for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { set<long long> hashset; for (int k = j + 1; k < n; k++) { // taking bigger data type // to avoid integer overflow: long long sum = nums[i] + nums[j]; sum += nums[k]; long long fourth = target - sum; if (hashset.find(fourth) != hashset.end()) { vector<int> temp = {nums[i], nums[j], nums[k], (int)(fourth)}; sort(temp.begin(), temp.end()); st.insert(temp); } // put the kth element into the hashset: hashset.insert(nums[k]); } } } vector<vector<int>> ans(st.begin(), st.end()); return ans; } int main() { vector<int> nums = {4, 3, 3, 4, 4, 2, 1, 2, 1, 1}; int target = 9; vector<vector<int>> ans = fourSum(nums, target); for (const auto& v : ans) { for (int x : v) cout << x << " "; cout << endl; } return 0; }
Output
Number of quadruplets: 3
Time Complexity : O(n^4) ,as there are four nested loops.
Space Complexity : O(1).
Solving 4Sum Using Hashing
Hashing is a technique used in data structures to store and retrieve data efficiently. It converts the input data (such as a number, string, or object) into a fixed-size value called a hash code or hash value, which is a key to point to the data's location.
Here, we will generate all possible triplets using nested for loops, and for every triplet, we will use hashing to find the fourth element of the quadruplets whose sum is equal to the given target, and to check that all quadruplets are distinct.
Algorithm
Here is the following algorithm we will follow to solve our given problem using hashing in C++.
- Fix the first element using a for loop with index i from 0 to n-1.
- For the second element, use another nested for loop inside it, with index j from i + 1 to n - 1.
- Now, before the third loop, declare a HashSet 'unordered_set<int> s' to store elements after index j.
- Then run the third loop with index k from j+1 to n-1.
- Inside that third loop, check for the fourth element by: fourth_element = target - (arr[i] + arr[j] + arr[k]).
- If a valid fourth element is found in the HashSet, then sort all the quadruplet values so that the set only stores unique combinations, and insert the sorted quadruplet into resSet.
- Convert the set of vectors into a vector<vector<int>> and return it.
Example
Here is an example code that uses hashing to solve the 4Sum problem in C++.
#include <bits/stdc++.h> using namespace std; vector<vector<int>> Sum(vector<int>& arr, int target) { int n = arr.size(); // set to store only unique sorted quadruplets set<vector<int>> resSet; // fixing each element using loop for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { // declared a HashSet to track elements for the 4th value unordered_set<int> s; // run third loop to find third and fourth elements for (int k = j + 1; k < n; k++) { int current_sum = arr[i] + arr[j] + arr[k]; int fourth_element = target - current_sum; // check if the fourth element exists in HashSet if (s.find(fourth_element) != s.end()) { vector<int> quad = {arr[i], arr[j], arr[k], fourth_element}; sort(quad.begin(), quad.end()); resSet.insert(quad); } // insert current element into the HashSet s.insert(arr[k]); } } } return vector<vector<int>>(resSet.begin(), resSet.end()); } int main() { vector<int> arr = {4, 6, 8, 10, 12, 2}; int target = 24; vector<vector<int>> result = Sum(arr, target); for (const auto& quad : result) { for (int val : quad) { cout << val << " "; } cout << endl; } return 0; }
Output
2 4 6 12 2 4 8 10
Time Complexity : O(n^3), as three nested loops are used.
Space Complexity : O(n + m), n is the size of an array, and m is the number of unique quadruplets.
Solving 4Sum Using Two Pointer
The two-pointer is a technique that uses two pointers or indices to traverse through a sorted array to find or count pairs, triplets, or other combinations.
Here, we will apply the two-pointer technique on a sorted array to avoid duplicates and to find quadruplets. In this, we will first sort the array and fix the first two elements using nested loops, and then use two pointers to traverse through the array from both ends to find the remaining two elements of the quadruplets.
Algorithm
Here is the following algorithm we will follow to solve our given problem using two pointers in C++.
- First, sort the given array and use the for loop with index i from 0 to n - 1. This i will represent one of the fixed pointers.
- Inside that loop, run another loop for another fixed pointer j from i + 1 to n - 1, and will again check for duplicates and will only perform further operations if the elements are different.
- Now, inside the second loop, initialize two pointers k = j + 1 and l = n - 1 from both ends.
- While k < l, calculate the sum of arr[i] + arr[j] + arr[k] + arr[l].
- If the sum is less than the given target, it means we need a larger value; therefore, move k forward (k++), as the array is sorted.
- If the sum is greater than the given target, move l backward (l--) for a smaller value.
- If the sum is equal to the target, then add that quadruplet to the result and move the pointers k and l to skip duplicate elements by checking the adjacent elements while moving both pointers.
- Now, return all unique quadruplets.
Example
Here is an example code that uses sorting and the two-pointer technique to solve the 4Sum problem in C++.
#include <iostream> #include <vector> #include <algorithm> using namespace std; vector<vector<int>> Sum(vector<int>& arr, int target) { vector<vector<int>> result; int n = arr.size(); // sorting the array sort(arr.begin(), arr.end()); // first loop for fixed pointer i for (int i = 0; i < n - 3; i++) { // skip duplicates for i if (i > 0 && arr[i] == arr[i - 1]) continue; // second loop for fixed pointer j for (int j = i + 1; j < n - 2; j++) { // skip duplicates for j if (j > i + 1 && arr[j] == arr[j - 1]) continue; // initializing two pointers int k = j + 1; int l = n - 1; while (k < l) { int sum = arr[i] + arr[j] + arr[k] + arr[l]; if (sum == target) { result.push_back({arr[i], arr[j], arr[k], arr[l]}); // moving k forward and skipping duplicates while (k < l && arr[k] == arr[k + 1]) k++; // moving l backward and skipping duplicates while (k < l && arr[l] == arr[l - 1]) l--; k++; l--; } else if (sum < target) { k++; } else { l--; } } } } return result; } int main() { vector<int> arr = {1, 0, -1, 0, -2, 2}; int target = 0; vector<vector<int>> result = Sum(arr, target); for (auto quad : result) { for (int num : quad) { cout << num << " "; } cout << endl; } return 0; }
Output
-2 -1 1 2 -2 0 0 2 -1 0 0 1
Time complexity: O(n^3),
O(n^2) for two nested loops and O(n) for two pointers.
Therefore, the total time complexity will be O(n²*n) = O(n³).
Space Complexity: O(1)
Conclusion
In this article, we have used three different methods to solve the 4-sum problem, that is,
Methods | Time Complexity | Space Complexity |
Four nested loops | O(n^4) | O(1) |
Three nested loops with Hashing | O(n^3) | O(n + m) |
Sorting and Two-Pointers | O(n^3) | O(1) |
By this, we can conclude that the two-pointer technique is the most optimal approach to solve the given problem with efficient time and space complexity.