4 Sum - Count quadruplets with given sum in an array
Given an array arr[] and a target value, the task is to find the count of quadruplets present in the given array having sum equal to the given target.
Examples:
Input: arr[] = [1, 5, 3, 1, 2, 10], target = 20
Output: 1
Explanation: Only quadruplet satisfying the conditions is arr[1] + arr[2] + arr[4] + arr[5] = 5 + 3 + 2 + 10 = 20.Input: arr[] = [1, 1, 1, 1, 1], target = 4
Output: 5
Explanation:
arr[0] + arr[1] + arr[2] + arr[3] = 4
arr[0] + arr[1] + arr[3] + arr[4] = 4
arr[0] + arr[1] + arr[2] + arr[4] = 4
arr[0] + arr[2] + arr[3] + arr[4] = 4
arr[1] + arr[2] + arr[3] + arr[4] = 4Input: arr = [4, 3, -13, 3], target = -3
Output: 1
Explanation: There is only 1 quadruplet with sum = -3, that is [4, 3, -13, 3].
Table of Content
Naive Approach - O(n^4) Time and O(1) Space
The idea is to generate all possible combinations of length 4 from the given array. For each quadruplet, if the sum equals target, then increment the counter by 1.
#include <iostream>
#include <vector>
using namespace std;
// Function to return the number of quadruplets
// with the given target sum
int countSum(vector<int>& arr, int target) {
int n = arr.size();
int count = 0;
// Loop over all possible quadruplets
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 (arr[i] + arr[j] + arr[k] + arr[l] == target) {
count++;
}
}
}
}
}
return count;
}
int main() {
vector<int> arr = {1, 1, 1, 1, 1};
int target = 4;
cout << countSum(arr, target) << endl;
return 0;
}
#include <stdio.h>
// Function to return the number of quadruplets with the given target sum
int countSum(int arr[], int n, int target) {
int count = 0;
// Loop over all possible quadruplets
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 (arr[i] + arr[j] + arr[k] + arr[l] == target) {
count++;
}
}
}
}
}
return count;
}
// Driver Code
int main() {
int arr[] = {1, 1, 1, 1, 1};
int n = sizeof(arr) / sizeof(arr[0]);
int target = 4;
printf("%d\n", countSum(arr, n, target));
return 0;
}
import java.util.*;
class GfG {
// Function to return the number of quadruplets with the given target sum
static int countSum(int[] arr, int target) {
int n = arr.length;
int count = 0;
// Loop over all possible quadruplets
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 (arr[i] + arr[j] + arr[k] + arr[l] == target) {
count++;
}
}
}
}
}
return count;
}
// Driver Code
public static void main(String[] args) {
int[] arr = {1, 1, 1, 1, 1};
int target = 4;
System.out.println(countSum(arr, target));
}
}
# Function to return the number of quadruplets with the given target sum
def countSum(arr, target):
n = len(arr)
count = 0
# Loop over all possible quadruplets
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 arr[i] + arr[j] + arr[k] + arr[l] == target:
count += 1
return count
if __name__ == "__main__":
arr = [1, 1, 1, 1, 1]
target = 4
print(countSum(arr, target))
using System;
class GfG {
// Function to return the number of quadruplets with the given target sum
static int countSum(int[] arr, int target) {
int n = arr.Length;
int count = 0;
// Loop over all possible quadruplets
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 (arr[i] + arr[j] + arr[k] + arr[l] == target) {
count++;
}
}
}
}
}
return count;
}
public static void Main() {
int[] arr = { 1, 1, 1, 1, 1 };
int target = 4;
Console.WriteLine(countSum(arr, target));
}
}
// Function to return the number of quadruplets with the given target sum
function countSum(arr, target) {
let n = arr.length;
let count = 0;
// Loop over all possible quadruplets
for (let i = 0; i < n - 3; i++) {
for (let j = i + 1; j < n - 2; j++) {
for (let k = j + 1; k < n - 1; k++) {
for (let l = k + 1; l < n; l++) {
if (arr[i] + arr[j] + arr[k] + arr[l] === target) {
count++;
}
}
}
}
}
return count;
}
// Driver Code
let arr = [1, 1, 1, 1, 1];
let target = 4;
console.log(countSum(arr, target));
Output
5
Time Complexity: O(n4), where n is the size of the given array.
Auxiliary Space: O(1)
Better Approach - O(n^3) Time and O(n) Space
The idea is to use Hash Map or Dictionary. For every pair (arr[i], arr[j]) where j > i, we simply use the logic of counting pairs for the subarray from (j + 1) to end of the array for target equals to given target - arr[i] - arr[j].
- Initialize the counter count with 0 to store the number of quadruplets.
- Traverse the given array over the range [0, n - 3) using the variable i. For each element arr[i], traverse the array again over the range [i + 1, n - 2) using the variable j and do the following:
- Find the value of the remaining sum(say rem) as (target - arr[i] - arr[j]).
- Count the number of pairs with sum = (target - arr[i] - arr[j]) in the subarray arr[j+1...n-1] and add it to count.
- After the above steps, print the value of count as the result.
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
// Returns number of pairs in arr[idx..n-1] with sum equal
// to 'target'
int getPairsCount(vector<int>& arr, int idx, int target);
// Function to return the number of quadruplets
// having the given target sum
int countSum(vector<int>& arr, int target) {
int n = arr.size();
int count = 0;
// Consider all pairs
for (int i = 0; i < n - 3; i++) {
for (int j = i + 1; j < n - 2; j++) {
// Find count for the current pair in
// subarray from j+1 to n-1
int rem = target - arr[i] - arr[j];
count += getPairsCount(arr, j+1, rem);
}
}
return count;
}
// Returns number of pairs in arr[idx..n-1] with sum equal
// to 'target'
int getPairsCount(vector<int>& arr, int idx, int target) {
unordered_map<int, int> m;
int count = 0;
// Traverse the vector
for (int i = idx; i < arr.size(); i++) {
// Check if the complement (k - arr[i])
// exists in the map
// If yes, increment count
if (m.find(target - arr[i]) != m.end()) {
count += m[target - arr[i]];
}
// Increment the frequency of arr[i]
m[arr[i]]++;
}
return count;
}
// Driver Code
int main() {
vector<int> arr = { 1, 1, 1, 1, 1 };
int target = 4;
cout << countSum(arr, target);
return 0;
}
import java.util.HashMap;
class GfG {
// Function to return the number of pairs in arr[idx..n-1] with sum equal to 'target'
static int getPairsCount(int[] arr, int idx, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
int count = 0;
// Traverse the array
for (int i = idx; i < arr.length; i++) {
if (map.containsKey(target - arr[i])) {
count += map.get(target - arr[i]);
}
map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);
}
return count;
}
// Function to return the number of quadruplets having the given target sum
static int countSum(int[] arr, int target) {
int count = 0;
// Consider all pairs
for (int i = 0; i < arr.length - 3; i++) {
for (int j = i + 1; j < arr.length - 2; j++) {
int rem = target - arr[i] - arr[j];
count += getPairsCount(arr, j + 1, rem);
}
}
return count;
}
// Driver Code
public static void main(String[] args) {
int[] arr = {1, 1, 1, 1, 1};
int target = 4;
System.out.println(countSum(arr, target));
}
}
from collections import defaultdict
# Function to return the number of pairs in arr[idx..n-1] with sum equal to 'target'
def getPairsCount(arr, idx, target):
count = 0
freq_map = defaultdict(int)
# Traverse the array
for i in range(idx, len(arr)):
if target - arr[i] in freq_map:
count += freq_map[target - arr[i]]
freq_map[arr[i]] += 1
return count
# Function to return the number of quadruplets having the given target sum
def countSum(arr, target):
count = 0
# Consider all pairs
for i in range(len(arr) - 3):
for j in range(i + 1, len(arr) - 2):
rem = target - arr[i] - arr[j]
count += getPairsCount(arr, j + 1, rem)
return count
if __name__ == "__main__":
arr = [1, 1, 1, 1, 1]
target = 4
print(countSum(arr, target))
using System;
using System.Collections.Generic;
class GfG {
// Function to return the number of pairs in arr[idx..n-1] with sum equal to 'target'
static int getPairsCount(int[] arr, int idx, int target) {
Dictionary<int, int> freqMap = new Dictionary<int, int>();
int count = 0;
// Traverse the array
for (int i = idx; i < arr.Length; i++) {
if (freqMap.ContainsKey(target - arr[i])) {
count += freqMap[target - arr[i]];
}
if (!freqMap.ContainsKey(arr[i])) {
freqMap[arr[i]] = 0;
}
freqMap[arr[i]]++;
}
return count;
}
// Function to return the number of quadruplets having the given target sum
static int countSum(int[] arr, int target) {
int count = 0;
// Consider all pairs
for (int i = 0; i < arr.Length - 3; i++) {
for (int j = i + 1; j < arr.Length - 2; j++) {
int rem = target - arr[i] - arr[j];
count += getPairsCount(arr, j + 1, rem);
}
}
return count;
}
// Driver Code
public static void Main() {
int[] arr = { 1, 1, 1, 1, 1 };
int target = 4;
Console.WriteLine(countSum(arr, target));
}
}
// Function to return the number of pairs in arr[idx..n-1] with sum equal to 'target'
function getPairsCount(arr, idx, target) {
const freqMap = {};
let count = 0;
// Traverse the array
for (let i = idx; i < arr.length; i++) {
if (freqMap[target - arr[i]]) {
count += freqMap[target - arr[i]];
}
freqMap[arr[i]] = (freqMap[arr[i]] || 0) + 1;
}
return count;
}
// Function to return the number of quadruplets having the given target sum
function countSum(arr, target) {
let count = 0;
// Consider all pairs
for (let i = 0; i < arr.length - 3; i++) {
for (let j = i + 1; j < arr.length - 2; j++) {
const rem = target - arr[i] - arr[j];
count += getPairsCount(arr, j + 1, rem);
}
}
return count;
}
// Driver Code
const arr = [1, 1, 1, 1, 1];
const target = 4;
console.log(countSum(arr, target));
Output
5
Time complexity: O(n3), where n is the size of the given array.
Auxiliary Space: O(n)
Efficient Approach - O(n^2) Time and O(n^2) Space
The idea is similar to the above approach using hashing. In this approach, we fix the 3rd element, then find and store the frequency of sums of all possible first two elements of any quadruplet of the given array. Follow the below steps to solve the problem:
- Initialize count = 0 and a hash map or dictionary to store count of all possible sums of the first two elements of possible quadruplets.
- Iterate over the array with arr[i] as the third element of the quadruplet.
- For each arr[i], loop j from [i + 1... n - 1] to find the fourth element and check if (target - arr[i] - arr[j]) exists in the hash map. If it does, add its frequency to count.
- After iterating over all possible fourth elements, traverse the array arr[] from j = 0 to i - 1 and increment the frequency of all sums arr[i] + arr[j]. This is needed because when we move to the next i, we need to look for possible pairs that come before i.
- Repeat the above steps for each element arr[i] and return count as the total number of quadruplets with the given target sum.
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
// Function to return the number of quadruplets
// having the given target sum
int countSum(vector<int>& arr, int target) {
int n = arr.size();
int count = 0;
// Store the frequency of sum of first two elements
unordered_map<int, int> freq;
// Traverse from 0 to n-1, where arr[i]
// is the 3rd element
for (int i = 0; i < n - 1; i++) {
// All possible 4th elements
for (int j = i + 1; j < n; j++) {
// Sum of last two elements
int temp = arr[i] + arr[j];
// Check for valid sum of the first two elements
count += freq[target - temp];
}
// Store frequency of all possible sums
// of first two elements
for (int j = 0; j < i; j++) {
int temp = arr[i] + arr[j];
freq[temp]++;
}
}
return count;
}
int main() {
vector<int> arr = { 1, 1, 1, 1, 1 };
int target = 4;
cout << countSum(arr, target);
return 0;
}
import java.util.HashMap;
class GfG {
// Function to return the number of quadruplets having the given target sum
static int countSum(int[] arr, int target) {
int count = 0;
int n = arr.length;
// Store the frequency of sum of first two elements
HashMap<Integer, Integer> map = new HashMap<>();
// Traverse from 0 to n-1, where arr[i] is the 3rd element
for (int i = 0; i < n - 1; i++) {
// All possible 4th elements
for (int j = i + 1; j < n; j++) {
int temp = arr[i] + arr[j];
count += map.getOrDefault(target - temp, 0);
}
// Store frequency of all possible sums of first two elements
for (int j = 0; j < i; j++) {
int temp = arr[i] + arr[j];
map.put(temp, map.getOrDefault(temp, 0) + 1);
}
}
return count;
}
public static void main(String[] args) {
int[] arr = {1, 1, 1, 1, 1};
int target = 4;
System.out.println(countSum(arr, target));
}
}
from collections import defaultdict
# Function to return the number of quadruplets having the given target sum
def countSum(arr, target):
count = 0
n = len(arr)
# Store the frequency of sum of first two elements
m = defaultdict(int)
# Traverse from 0 to n-1, where arr[i] is the 3rd element
for i in range(n - 1):
# All possible 4th elements
for j in range(i + 1, n):
temp = arr[i] + arr[j]
count += m[target - temp]
# Store frequency of all possible sums of first two elements
for j in range(i):
temp = arr[i] + arr[j]
m[temp] += 1
return count
if __name__ == "__main__":
arr = [1, 1, 1, 1, 1]
target = 4
print(countSum(arr, target))
using System;
using System.Collections.Generic;
class GfG {
// Function to return the number of quadruplets having the given target sum
static int countSum(int[] arr, int target) {
int count = 0;
int n = arr.Length;
// Store the frequency of sum of first two elements
Dictionary<int, int> map = new Dictionary<int, int>();
// Traverse from 0 to n-1, where arr[i] is the 3rd element
for (int i = 0; i < n - 1; i++) {
// All possible 4th elements
for (int j = i + 1; j < n; j++) {
int temp = arr[i] + arr[j];
if (map.ContainsKey(target - temp)) {
count += map[target - temp];
}
}
// Store frequency of all possible sums of first two elements
for (int j = 0; j < i; j++) {
int temp = arr[i] + arr[j];
if (!map.ContainsKey(temp)) {
map[temp] = 0;
}
map[temp]++;
}
}
return count;
}
public static void Main() {
int[] arr = { 1, 1, 1, 1, 1 };
int target = 4;
Console.WriteLine(countSum(arr, target));
}
}
// Function to return the number of quadruplets having the given target sum
function countSum(arr, target) {
let count = 0;
let n = arr.length;
// Store the frequency of sum of first two elements
let map = {};
// Traverse from 0 to n-1, where arr[i] is the 3rd element
for (let i = 0; i < n - 1; i++) {
// All possible 4th elements
for (let j = i + 1; j < n; j++) {
let temp = arr[i] + arr[j];
if (map[target - temp]) {
count += map[target - temp];
}
}
// Store frequency of all possible sums of first two elements
for (let j = 0; j < i; j++) {
let temp = arr[i] + arr[j];
map[temp] = (map[temp] || 0) + 1;
}
}
return count;
}
// Driver Code
const arr = [1, 1, 1, 1, 1];
const target = 4;
console.log(countSum(arr, target));
Output
5
Time Complexity: O(n2), where n is the size of the given array.
Auxiliary Space: O(n2), as we are storing sum of all possible pairs in the hash map.