Given an integer array nums and an integer target. Return all quadruplets [nums[a], nums[b], nums[c], nums[d]] such that:
· a, b, c, d are all distinct valid indices of nums.
· nums[a] + nums[b] + nums[c] + nums[d] == target.
Notice that the solution set must not contain duplicate quadruplets. One element can be a part of multiple quadruplets. The output and the quadruplets can be returned in any order.
Input: nums = [1, -2, 3, 5, 7, 9], target = 7
Output: [[-2, 1, 3, 5]]
Explanation: nums[1] + nums[0] + nums[2] + nums[3] = 7
Input: nums = [7, -7, 1, 2, 14, 3], target = 9
Output: []
Explanation: No quadruplets are present which add upto 9
Input: nums = [1, 1, 3, 4, -3], target = 5
(Give answer with the output and quadruplets sorted in ascending order)
The idea is to check all possible quadruplets and among them, consider the ones whose sum is equal to the given target. And before considering them as our answer, sort the quadruplets in ascending order.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
//function to find quadruplets having sum equal to target
vector<vector<int>> fourSum(vector<int>& nums, int target) {
// Size of the array
int n = nums.size();
// Set to store unique quadruplets
set<vector<int>> st;
// Checking all possible quadruplets
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
for (int l = k + 1; l < n; l++) {
// Calculate the sum of the current quadruplet
long long sum = nums[i] + nums[j] + nums[k] + nums[l];
// Check if the sum matches the target
if (sum == target) {
vector<int> temp = {nums[i], nums[j], nums[k], nums[l]};
// Sort the quadruplet to ensure uniqueness
sort(temp.begin(), temp.end());
st.insert(temp);
}
}
}
}
}
// Convert set to vector (unique quadruplets)
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;
// Create an instance of Solution class
Solution sol;
vector<vector<int>> ans = sol.fourSum(nums, target);
// Print the result
cout << "The quadruplets are: \n";
for (auto& it : ans) {
cout << "[";
for (auto& ele : it) {
cout << ele << " ";
}
cout << "] ";
}
cout << "\n";
return 0;
}
import java.util.*;
class Solution {
//function to find quadruplets having sum equal to target
public List<List<Integer>> fourSum(int[] nums, int target) {
//size of the array
int n = nums.length;
// Set to store unique quadruplets
Set<List<Integer>> set = new HashSet<>();
// Checking all possible quadruplets
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
for (int l = k + 1; l < n; l++) {
// Calculate the sum of the current quadruplet
long sum = nums[i] + nums[j] + nums[k] + nums[l];
// Check if the sum matches the target
if (sum == target) {
List<Integer> temp = Arrays.asList(nums[i], nums[j], nums[k], nums[l]);
// Sort the quadruplet to ensure uniqueness
Collections.sort(temp);
set.add(temp);
}
}
}
}
}
// Convert set to list (unique quadruplets)
return new ArrayList<>(set);
}
public static void main(String[] args) {
int[] nums = {4, 3, 3, 4, 4, 2, 1, 2, 1, 1};
int target = 9;
//create an instance of the Solution class
Solution sol = new Solution();
List<List<Integer>> ans = sol.fourSum(nums, target);
// Print the result
System.out.println("The quadruplets are: ");
for (List<Integer> quad : ans) {
System.out.print("[");
for (int num : quad) {
System.out.print(num + " ");
}
System.out.print("] ");
}
System.out.println();
}
}
from typing import List
class Solution:
#function to find quadruplets having sum equal to target
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
#size of array
n = len(nums)
#Set to store unique quadruplets
ans = set()
# Checking all possible quadruplets
for i in range(n):
for j in range(i + 1, n):
for k in range(j + 1, n):
for l in range(k + 1, n):
# Calculate the sum of the current quadruplet
sum_val = nums[i] + nums[j] + nums[k] + nums[l]
# Check if the sum matches the target
if sum_val == target:
temp = [nums[i], nums[j], nums[k], nums[l]]
# Sort the quadruplet to ensure uniqueness
temp.sort()
ans.add(tuple(temp))
return list(ans)
if __name__ == "__main__":
nums = [4, 3, 3, 4, 4, 2, 1, 2, 1, 1]
target = 9
#Create an instance of Solution class
sol = Solution()
ans = sol.fourSum(nums, target)
# Print the result
print("The quadruplets are: ")
for quad in ans:
print(f"[{', '.join(map(str, quad))}]")
class Solution {
// Function to find quadruplets with sum equal to target
fourSum(nums, target) {
const n = nums.length;
const resultSet = new Set();
// Checking all possible quadruplets
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
for (let k = j + 1; k < n; k++) {
for (let l = k + 1; l < n; l++) {
// Calculate the sum of the current quadruplet
const sum = nums[i] + nums[j] + nums[k] + nums[l];
// Check if the sum matches the target
if (sum === target) {
const temp = [nums[i], nums[j], nums[k], nums[l]];
// Sort the quadruplet to ensure uniqueness
temp.sort((a, b) => a - b);
resultSet.add(temp.join(',')); // Use join to store as unique string
}
}
}
}
}
// Convert set back to array of arrays (unique quadruplets)
const ans = Array.from(resultSet).map(item => item.split(',').map(Number));
return ans;
}
}
// Sample usage
const nums = [4, 3, 3, 4, 4, 2, 1, 2, 1, 1];
const target = 9;
// Create an instance of Solution class
const sol = new Solution();
const ans = sol.fourSum(nums, target);
// Print the result
console.log("The quadruplets are:");
ans.forEach(quadruplet => {
console.log(`[${quadruplet.join(' ')}]`);
});
The better approach uses simple mathematics where some calculative parameter is taken in RHS(right hand side) to compute the result.
For example if a + b + c + d = 0, then a + b + c = -d. Similar idea is used here.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
// Size of the array
int n = nums.size();
// Set to store unique quadruplets
set<vector<int>> st;
// Checking all possible quadruplets
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// Set to store elements seen so far in the loop
set<long long> hashset;
for (int k = j + 1; k < n; k++) {
// Calculate the fourth element needed to reach target
long long sum = nums[i] + nums[j];
sum += nums[k];
long long fourth = target - sum;
/* Find if fourth element exists in
hashset (complements seen so far)*/
if (hashset.find(fourth) != hashset.end()) {
// Found a quadruplet that sums up to target
vector<int> temp = {nums[i], nums[j], nums[k], static_cast<int>(fourth)};
// Sort the quadruplet to ensure uniqueness
sort(temp.begin(), temp.end());
st.insert(temp);
}
// Insert the kth element into hashset for future checks
hashset.insert(nums[k]);
}
}
}
// Convert set to vector (unique quadruplets)
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;
// Create an instance of Solution class
Solution sol;
vector<vector<int>> ans = sol.fourSum(nums, target);
// Print the result
cout << "The quadruplets are: \n";
for (auto& it : ans) {
cout << "[";
for (auto& ele : it) {
cout << ele << " ";
}
cout << "] ";
}
cout << "\n";
return 0;
}
import java.util.*;
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<>();
int n = nums.length;
// Set to store unique quadruplets
Set<List<Integer>> set = new HashSet<>();
// Checking all possible quadruplets
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// Set to store elements seen so far in the loop
Set<Long> hashset = new HashSet<>();
for (int k = j + 1; k < n; k++) {
/* Calculate the fourth element
needed to reach target*/
long sum = (long) nums[i] + nums[j] + nums[k];
long fourth = target - sum;
/* Find if fourth element exists in
hashset (complements seen so far)*/
if (hashset.contains(fourth)) {
// Found a quadruplet that sums up to target
List<Integer> temp = Arrays.asList(nums[i], nums[j], nums[k], (int) fourth);
Collections.sort(temp);
set.add(temp);
}
// Insert the kth element into hashset for future checks
hashset.add((long) nums[k]);
}
}
}
// Convert set to list (unique quadruplets)
ans.addAll(set);
return ans;
}
public static void main(String[] args) {
int[] nums = {4, 3, 3, 4, 4, 2, 1, 2, 1, 1};
int target = 9;
// Create an instance of Solution class
Solution sol = new Solution();
List<List<Integer>> ans = sol.fourSum(nums, target);
// Print the result
System.out.println("The quadruplets are:");
for (List<Integer> quad : ans) {
System.out.print("[");
for (int num : quad) {
System.out.print(num + " ");
}
System.out.println("]");
}
}
}
from typing import List
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
ans = []
n = len(nums)
# Set to store unique quadruplets
st = set()
# Checking all possible quadruplets
for i in range(n):
for j in range(i + 1, n):
# Set to store elements seen so far in the loop
hashset = set()
for k in range(j + 1, n):
# Calculate the fourth element needed to reach target
summ = nums[i] + nums[j] + nums[k]
fourth = target - summ
""" Find if fourth element exists in
hashset (complements seen so far)"""
if fourth in hashset:
# Found a quadruplet that sums up to target
temp = sorted([nums[i], nums[j], nums[k], fourth])
st.add(tuple(temp))
# Insert the kth element into hashset for future checks
hashset.add(nums[k])
# Convert set to list (unique quadruplets)
ans = [list(t) for t in st]
return ans
if __name__ == "__main__":
nums = [4, 3, 3, 4, 4, 2, 1, 2, 1, 1]
target = 9
# Create an instance of Solution class
sol = Solution()
ans = sol.fourSum(nums, target)
# Print the result
print("The quadruplets are:")
for quad in ans:
print(quad)
class Solution {
// Function to find quadruplets with sum equal to target
fourSum(nums, target) {
let ans = [];
let n = nums.length;
// Set to store unique quadruplets
let set = new Set();
// Checking all possible quadruplets
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
// Set to store elements seen so far in the loop
let hashset = new Set();
for (let k = j + 1; k < n; k++) {
/* Calculate the fourth element
needed to reach target*/
let sum = nums[i] + nums[j] + nums[k];
let fourth = target - sum;
/* Find if fourth element exists in
hashset (complements seen so far)*/
if (hashset.has(fourth)) {
// Found a quadruplet that sums up to target
let temp = [nums[i], nums[j], nums[k], fourth].sort((a, b) => a - b);
set.add(temp.join());
}
// Insert the kth element into hashset for future checks
hashset.add(nums[k]);
}
}
}
// Convert set to array (unique quadruplets)
set.forEach(item => {
ans.push(item.split(',').map(Number));
});
return ans;
}
}
// Sample usage
const nums = [4, 3, 3, 4, 4, 2, 1, 2, 1, 1];
const target = 9;
// Create an instance of Solution class
const sol = new Solution();
const ans = sol.fourSum(nums, target);
// Print the result
console.log("The quadruplets are:");
ans.forEach(quadruplet => {
console.log(`[${quadruplet.join(' ')}]`);
});
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
//function to find quadruplets having sum equals to target
vector<vector<int>> fourSum(vector<int>& nums, int target) {
// Vector to store the quadruplets that sum up to target
vector<vector<int>> ans;
int n = nums.size();
// Sort the input array nums
sort(nums.begin(), nums.end());
// Iterate through the array to find quadruplets
for (int i = 0; i < n; i++) {
// Skip duplicates for i
if (i > 0 && nums[i] == nums[i - 1])
continue;
for (int j = i + 1; j < n; j++) {
// Skip duplicates for j
if (j > i + 1 && nums[j] == nums[j - 1])
continue;
// Two pointers approach
int k = j + 1;
int l = n - 1;
while (k < l) {
long long sum = nums[i] + nums[j] + nums[k] + nums[l];
if (sum == target) {
// Found a quadruplet that sums up to target
vector<int> temp = {nums[i], nums[j], nums[k], nums[l]};
ans.push_back(temp);
// Skip duplicates for k and l
k++;
l--;
while (k < l && nums[k] == nums[k - 1]) k++;
while (k < l && nums[l] == nums[l + 1]) l--;
} else if (sum < target) {
k++;
} else {
l--;
}
}
}
}
return ans;
}
};
int main() {
vector<int> nums = {4, 3, 3, 4, 4, 2, 1, 2, 1, 1};
int target = 9;
// Create an instance of Solution class
Solution sol;
vector<vector<int>> ans = sol.fourSum(nums, target);
// Print the result
cout << "The quadruplets are: \n";
for (auto& it : ans) {
cout << "[";
for (auto& ele : it) {
cout << ele << " ";
}
cout << "] ";
}
cout << "\n";
return 0;
}
import java.util.*;
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<>();
int n = nums.length;
// Sort the input array nums
Arrays.sort(nums);
// Iterate through the array to find quadruplets
for (int i = 0; i < n; i++) {
// Skip duplicates for i
if (i > 0 && nums[i] == nums[i - 1])
continue;
for (int j = i + 1; j < n; j++) {
// Skip duplicates for j
if (j > i + 1 && nums[j] == nums[j - 1])
continue;
// Two pointers approach
int k = j + 1;
int l = n - 1;
while (k < l) {
long sum = (long) nums[i] + nums[j] + nums[k] + nums[l];
if (sum == target) {
// Found a quadruplet that sums up to target
List<Integer> temp = Arrays.asList(nums[i], nums[j], nums[k], nums[l]);
ans.add(temp);
// Skip duplicates for k and l
k++;
l--;
while (k < l && nums[k] == nums[k - 1]) k++;
while (k < l && nums[l] == nums[l + 1]) l--;
} else if (sum < target) {
k++;
} else {
l--;
}
}
}
}
return ans;
}
public static void main(String[] args) {
int[] nums = {4, 3, 3, 4, 4, 2, 1, 2, 1, 1};
int target = 9;
// Create an instance of Solution class
Solution sol = new Solution();
List<List<Integer>> ans = sol.fourSum(nums, target);
// Print the result
System.out.println("The quadruplets are: ");
for (List<Integer> quad : ans) {
System.out.print("[");
for (int num : quad) {
System.out.print(num + " ");
}
System.out.println("]");
}
}
}
from typing import List
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
ans = []
n = len(nums)
# Sort the input array nums
nums.sort()
# Iterate through the array to find quadruplets
for i in range(n):
# Skip duplicates for i
if i > 0 and nums[i] == nums[i - 1]:
continue
for j in range(i + 1, n):
# Skip duplicates for j
if j > i + 1 and nums[j] == nums[j - 1]:
continue
# Two pointers approach
k = j + 1
l = n - 1
while k < l:
sum_val = nums[i] + nums[j] + nums[k] + nums[l]
if sum_val == target:
# Found a quadruplet that sums up to target
temp = [nums[i], nums[j], nums[k], nums[l]]
ans.append(temp)
# Skip duplicates for k and l
k += 1
l -= 1
while k < l and nums[k] == nums[k - 1]:
k += 1
while k < l and nums[l] == nums[l + 1]:
l -= 1
elif sum_val < target:
k += 1
else:
l -= 1
return ans
if __name__ == "__main__":
nums = [4, 3, 3, 4, 4, 2, 1, 2, 1, 1]
target = 9
# Create an instance of Solution class
sol = Solution()
ans = sol.fourSum(nums, target)
# Print the result
print("The quadruplets are: ")
for quad in ans:
print(quad)
class Solution {
// Function to find quadruplets with sum equal to target
fourSum(nums, target) {
let ans = [];
let n = nums.length;
// Sort the input array nums
nums.sort((a, b) => a - b);
// Iterate through the array to find quadruplets
for (let i = 0; i < n; i++) {
// Skip duplicates for i
if (i > 0 && nums[i] === nums[i - 1])
continue;
for (let j = i + 1; j < n; j++) {
// Skip duplicates for j
if (j > i + 1 && nums[j] === nums[j - 1])
continue;
// Two pointers approach
let k = j + 1;
let l = n - 1;
while (k < l) {
let sum = nums[i] + nums[j] + nums[k] + nums[l];
if (sum === target) {
// Found a quadruplet that sums up to target
ans.push([nums[i], nums[j], nums[k], nums[l]]);
// Skip duplicates for k and l
k++;
l--;
while (k < l && nums[k] === nums[k - 1]) k++;
while (k < l && nums[l] === nums[l + 1]) l--;
} else if (sum < target) {
k++;
} else {
l--;
}
}
}
}
return ans;
}
}
// Sample usage
const nums = [4, 3, 3, 4, 4, 2, 1, 2, 1, 1];
const target = 9;
// Create an instance of Solution class
const sol = new Solution();
const ans = sol.fourSum(nums, target);
// Print the result
console.log("The quadruplets are:");
ans.forEach(quadruplet => {
console.log(`[${quadruplet.join(' ')}]`);
});
Q: How does the two-pointer technique work in this context?
A: Fix two elements, nums[i] and nums[j]. Use two pointers, left and right, on the remaining part of the array to find pairs that sum to target−nums[i]−nums[j]. Adjust pointers:If the sum is less than the target, move left forward to increase the sum. If the sum is greater, move right backward to decrease the sum.
Q: How do we avoid duplicate quadruplets?
A: Skip duplicate values for nums[i], nums[j], nums[left], and nums[right] during the iterations.
Q: What if the input array is unsorted?
A: Sorting is part of the solution and is necessary for efficient implementation. Sorting adds O(nlogn) complexity, which is manageable compared to O(n^3).