4 Sum - Find all Quadruplets with Given Sum
Last Updated : 20 Oct, 2024
Given an array arr[] and a target value, the task is to find all possible indexes (i, j, k, l) of quadruplets (arr[i], arr[j], arr[k], arr[l]) whose sum is given target and all indexes in a quadruple are distinct (i != j, j != k, and k != l). We need to return indexes of a quadruple in sorted order, i.e., i < j < k < l.
Examples:
Input: arr[] = {1, 5, 3, 1, 2, 10}, target = 20
Output: [1, 2, 4, 5]
Explanation: Only quadruplet satisfying the conditions is arr[1] + arr[2] + arr[4] + arr[5] = 5 + 3 + 2 + 10 = 20.
Input: arr[] = {4, 5, 3, 1, 2, 4}, target = 13
Output: [[0, 1, 2, 5], [0, 1, 2, 3], [1, 2, 3, 5]]
Explanation: Three quadruplets with sum 13 are:
arr[0] + arr[2] + arr[4] + arr[5] = 4 + 3 + 2 + 4 = 13
arr[0] + arr[1] + arr[2] + arr[3] = 4 + 5 + 3 + 1 = 13
arr[1] + arr[2] + arr[3] + arr[5] = 5 + 3 + 1 + 4 = 13
Input: arr[] = {1, 1, 1, 1, 1}, target = 4
Output: [[1, 1, 2, 3], [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4], [1, 2, 3, 4]]
Explanation:
arr[0] + arr[1] + arr[2] + arr[3] = 4
arr[0] + arr[1] + arr[2] + arr[4] = 4
arr[0] + arr[1] + arr[3] + arr[4] = 4
arr[0] + arr[2] + arr[3] + arr[4] = 4
arr[1] + arr[2] + arr[3] + arr[4] = 4
Naive Approach - O(n^4) Time and O(1) Space
The simplest approach is to generate all possible quadruplets from the given array arr[] and if the sum of elements of the quadruplets is equal to target, then add it to the result.
C++ #include <iostream> #include <vector> using namespace std; vector<vector<int>> fourSum(vector<int>& arr, int target) { vector<vector<int>> res; int n = arr.size(); // Four nested loops to generate all quadruples for (int i = 0; i < n - 3; i++) { for (int j = i + 1; j < n - 2; j++) { for (int k = j + 1; k < n - 1; k++) { for (int l = k + 1; l < n; l++) { // If the sum of the quadruple equals the // target, add it to the result if (arr[i] + arr[j] + arr[k] + arr[l] == target) { res.push_back({i, j, k, l}); } } } } } return res; } int main() { vector<int> arr = {1, 0, -1, 0, -2, 2}; int target = 0; vector<vector<int>> ans = fourSum(arr, target); for (auto v : ans) { for (auto x : v) { cout << x << " "; } cout << endl; } return 0; }
Java import java.util.ArrayList; import java.util.List; public class FourSum { public static List<List<Integer>> fourSum(int[] arr, int target) { List<List<Integer>> res = new ArrayList<>(); int n = arr.length; // Four nested loops to generate all quadruples for (int i = 0; i < n - 3; i++) { for (int j = i + 1; j < n - 2; j++) { for (int k = j + 1; k < n - 1; k++) { for (int l = k + 1; l < n; l++) { // If the sum of the quadruple equals the // target, add it to the result if (arr[i] + arr[j] + arr[k] + arr[l] == target) { res.add(List.of(i, j, k, l)); } } } } } return res; } public static void main(String[] args) { int[] arr = {1, 0, -1, 0, -2, 2}; int target = 0; List<List<Integer>> ans = fourSum(arr, target); for (List<Integer> v : ans) { for (int x : v) { System.out.print(x + " "); } System.out.println(); } } }
Python def four_sum(arr, target): res = [] n = len(arr) # Four nested loops to generate all quadruples for i in range(n - 3): for j in range(i + 1, n - 2): for k in range(j + 1, n - 1): for l in range(k + 1, n): # If the sum of the quadruple equals # the target, add it to the result if arr[i] + arr[j] + arr[k] + arr[l] == target: res.append([i, j, k, l]) return res # Driver Code arr = [1, 0, -1, 0, -2, 2] target = 0 ans = four_sum(arr, target) for quad in ans: print(f"{quad[0]} {quad[1]} {quad[2]} {quad[3]}")
Efficient Approach - O(n^4) Time and O(n^2) Space
The above approach can also be optimized by using the idea of generating all possible pairs of the given array. Follow the given steps to solve the problem:
- Initialize a Hash Map, say mp that stores all possible pairs with a given pair sum Pairs sum is used as key and an array of pairs as value.
- Generate all possible pairs and store their sums as keys and pairs themselves as values in mp.
- Now, generate all possible pairs of the given array again and for each sum of all pairs of elements (arr[i], arr[j]) if the value (target - sum) exists in the Hash Map mp, then store the current quadruplets in the result set.
- We use a set for result to avoid duplicates. Before we insert a quadruple in the result set, we sort it as per the question requirements.
- Finally, we move all the result set quadruples in an array and return the array.
Below is the implementation of the above approach:
C++ #include <bits/stdc++.h> using namespace std; vector<vector<int>> fourSum(vector<int>& arr, int target) { int n = arr.size(); unordered_map<int, vector<pair<int, int>>> mp; // Ideally we should us an unordered_set here, but C++ // does not support vector as a key in an unordered_set // So we have used set to keep the code simple. However // set internally uses Red Black Tree and has O(Log n) // time complexities for operations set<vector<int>> resset; // Store all pairs for every possible pairs sum for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { mp[arr[i] + arr[j]].push_back({i, j}); } } // Pick the first two elements for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { // Find pairs with the remaining sum int rem = target - arr[i] - arr[j]; if (mp.find(rem) != mp.end()) { auto& pairs = mp[rem]; for (auto& p : pairs) { // Ensure no two indexes are same in a quaduple and // all indexes are in sorted order if (p.first != i && p.second != i && p.first != j && p.second != j) { vector<int> curr = {p.first, p.second, i, j}; sort(curr.begin(), curr.end()); resset.insert(curr); } } } } } vector<vector<int>> res(resset.begin(), resset.end()); return res; } // Driver Code int main() { vector<int> arr = {1, 1, 1, 1, 1}; int target = 4; vector<vector<int>> res = fourSum(arr, target); for (auto& quad : res) { for (int num : quad) { cout << num << " "; } cout << endl; } return 0; }
Java import java.util.*; public class FourSum { public static List<List<Integer>> fourSum(int[] arr, int target) { int n = arr.length; Map<Integer, List<int[]>> mp = new HashMap<>(); Set<List<Integer>> resset = new HashSet<>(); // Store all pairs for every possible pairs sum for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { mp.computeIfAbsent(arr[i] + arr[j], k -> new ArrayList<>()).add(new int[]{i, j}); } } // Pick the first two elements for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { // Find pairs with the remaining sum int rem = target - arr[i] - arr[j]; if (mp.containsKey(rem)) { for (int[] p : mp.get(rem)) { // Ensure no two indexes are the same in a quadruple // And all indexes are in sorted order if (p[0] != i && p[1] != i && p[0] != j && p[1] != j) { List<Integer> curr = Arrays.asList(p[0], p[1], i, j); Collections.sort(curr); resset.add(curr); } } } } } return new ArrayList<>(resset); } public static void main(String[] args) { int[] arr = {1, 1, 1, 1, 1}; int target = 4; List<List<Integer>> res = fourSum(arr, target); for (List<Integer> quad : res) { quad.forEach(num -> System.out.print(num + " ")); System.out.println(); } } }
Python from collections import defaultdict def four_sum(arr, target): n = len(arr) mp = defaultdict(list) resset = set() # Set to avoid duplicates # Store all pairs for every possible pairs sum for i in range(n): for j in range(i + 1, n): mp[arr[i] + arr[j]].append((i, j)) # Pick the first two elements for i in range(n - 1): for j in range(i + 1, n): # Find pairs with the remaining sum rem = target - arr[i] - arr[j] if rem in mp: for p in mp[rem]: # Ensure no two indexes are the same in a quadruple # and all indexes are in sorted order if p[0] != i and p[1] != i and p[0] != j and p[1] != j: curr = tuple(sorted([p[0], p[1], i, j])) resset.add(curr) return [list(quad) for quad in resset] # Driver Code arr = [1, 1, 1, 1, 1] target = 4 res = four_sum(arr, target) for quad in res: print(" ".join(map(str, quad)))
Similar Reads
Java Program to Find all triplets with zero sum Given an array of distinct elements. The task is to find triplets in the array whose sum is zero. Examples :Â Input : arr[] = {0, -1, 2, -3, 1} Output : (0 -1 1), (2 -3 1) Explanation : The triplets with zero sum are 0 + -1 + 1 = 0 and 2 + -3 + 1 = 0 Input : arr[] = {1, -2, 1, 0, 5} Output : 1 -2 1
6 min read
Java Program to Find a triplet that sum to a given value Given an array and a value, find if there is a triplet in array whose sum is equal to the given value. If there is such a triplet present in array, then print the triplet and return true. Else return false. Examples:Â Â Input: array = {12, 3, 4, 1, 6, 9}, sum = 24;Â Output: 12, 3, 9Â Explanation: There
7 min read
Java Program to Count triplets with sum smaller than a given value Given an array of distinct integers and a sum value. Find count of triplets with sum smaller than given sum value. The expected Time Complexity is O(n2).Examples:Â Â Input : arr[] = {-2, 0, 1, 3} sum = 2. Output : 2 Explanation : Below are triplets with sum less than 2 (-2, 0, 1) and (-2, 0, 3) Input
4 min read
Java Program For Finding A Triplet From Three Linked Lists With Sum Equal To A Given Number Given three linked lists, say a, b and c, find one node from each list such that the sum of the values of the nodes is equal to a given number. For example, if the three linked lists are 12->6->29, 23->5->8, and 90->20->59, and the given number is 101, the output should be triple "6 5 90".In the fol
4 min read
Java Program to Find a triplet such that sum of two equals to third element Given an array of integers, you have to find three numbers such that the sum of two elements equals the third element.Examples: Input: {5, 32, 1, 7, 10, 50, 19, 21, 2}Output: 21, 2, 19 Input: {5, 32, 1, 7, 10, 50, 19, 21, 0}Output: no such triplet exist Question source: Arcesium Interview Experience
5 min read