Count of ways to choose 4 unique position elements one from each Array to make sum at most K
Last Updated :
12 Nov, 2023
Given four arrays A[], B[], C[], D[] and an integer K. The task is to find the number of combinations of four unique indices p, q, r, s such that A[p] + B[q] + C[r] + D[s] ≤ K.
Examples:
Input: A = {2, 3}, B = {5, 2}, C = {0}, D = {1, 2}, K = 6
Output: 3
Explanation: The following are the required combinations:
{2, 2, 0, 1}, {2, 2, 0, 2}, {3, 2, 0, 1}
Input: A = {1, 1}, B = {0}, C = {0}, D = {0}, K = 1
Output: 2
Naive approach: The brute force would be to build the sum of all combinations of four numbers, using four nested loops, and count how many of those sums are at most K.
Time Complexity: O(N4) where N is the maximum size among those four arrays
Auxiliary Space: O(1)
Efficient Approach: Improve the above method by using Divide and Conquer and Binary Search. Follow the steps mentioned below to solve the problem:
- Generate all possible pair combinations for A, B, and C, D.
- Assume each array has length n, then we will have two arrays, each with length n*n. Let it be merge1 and merge2.
- Sort one of the merge array, let’s say merge2.
- Iterate through the unsorted merge1 array and find how many elements from merge2 can be paired up with a sum less than or equal to K. It can easily be done by using binary search.
Below is the implementation of the above method.
C++
#include <bits/stdc++.h>
using namespace std;
int fourSumLessThanK(vector< int >& A, vector< int >& B,
vector< int >& C, vector< int >& D,
int K)
{
vector< int > merge1;
vector< int > merge2;
int res = 0;
for ( int i : A) {
for ( int j : B) {
merge1.push_back(i + j);
}
}
for ( int i : C) {
for ( int j : D) {
merge2.push_back(i + j);
}
}
sort(merge2.begin(), merge2.end());
for ( int i : merge1) {
int l = 0, r = merge2.size() - 1;
int pos = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (merge2[mid] + i <= K) {
pos = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
res += pos + 1;
}
return res;
}
int main()
{
vector< int > A = { 2, 3 };
vector< int > B = { 5, 2 };
vector< int > C = { 0 };
vector< int > D = { 1, 2 };
int K = 6;
cout << fourSumLessThanK(A, B, C, D, K);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int fourSumLessThanK( int A[], int B[],
int C[], int D[],
int K)
{
List<Integer> merge1= new ArrayList<Integer>();
List<Integer> merge2= new ArrayList<Integer>();
int res = 0 ;
for ( int i = 0 ; i < A.length; i++) {
for ( int j = 0 ; j < B.length; j++) {
merge1.add(A[i] + B[j]);
}
}
for ( int i = 0 ; i < C.length; i++) {
for ( int j = 0 ; j < D.length; j++) {
merge2.add(C[i] + D[j]);
}
}
Collections.sort(merge2);
for ( int i = 0 ; i < merge1.size(); i++) {
int l = 0 , r = merge2.size() - 1 ;
int pos = - 1 ;
while (l <= r) {
int mid = l + (r - l) / 2 ;
if (merge2.get(mid) + merge1.get(i) <= K) {
pos = mid;
l = mid + 1 ;
}
else {
r = mid - 1 ;
}
}
res += pos + 1 ;
}
return res;
}
public static void main (String[] args) {
int A[] = { 2 , 3 };
int B[] = { 5 , 2 };
int C[] = { 0 };
int D[] = { 1 , 2 };
int K = 6 ;
System.out.println(fourSumLessThanK(A, B, C, D, K));
}
}
|
Python3
def fourSumLessThanK(A, B, C, D, K):
merge1 = [];
merge2 = [];
res = 0 ;
for i in range ( len (A)):
for j in range ( len (B)):
merge1.append(A[i] + B[j]);
for i in range ( len (C)):
for j in range ( len (D)):
merge2.append(C[i] + D[j]);
merge2.sort()
for i in range ( len (merge1)):
l = 0 ;
r = len (merge2) - 1 ;
pos = - 1 ;
while (l < = r):
mid = (l + r) / / 2 ;
if (merge2[mid] + merge1[i] < = K):
pos = mid;
l = mid + 1 ;
else :
r = mid - 1 ;
res = res + pos + 1 ;
return res;
A = [ 2 , 3 ];
B = [ 5 , 2 ];
C = [ 0 ];
D = [ 1 , 2 ];
K = 6 ;
print (fourSumLessThanK(A, B, C, D, K));
|
C#
using System;
using System.Collections;
class GFG {
static int fourSumLessThanK( int []A, int []B,
int []C, int []D,
int K)
{
ArrayList merge1 = new ArrayList();
ArrayList merge2 = new ArrayList();
int res = 0;
for ( int i = 0; i < A.Length; i++) {
for ( int j = 0; j < B.Length; j++) {
merge1.Add(A[i] + B[j]);
}
}
for ( int i = 0; i < C.Length; i++) {
for ( int j = 0; j < D.Length; j++) {
merge2.Add(C[i] + D[j]);
}
}
merge2.Sort();
for ( int i = 0; i < merge1.Count; i++) {
int l = 0, r = merge2.Count - 1;
int pos = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (( int )merge2[mid] + ( int )merge1[i] <= K) {
pos = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
res += pos + 1;
}
return res;
}
public static void Main () {
int []A = { 2, 3 };
int []B = { 5, 2 };
int []C = { 0 };
int []D = { 1, 2 };
int K = 6;
Console.WriteLine(fourSumLessThanK(A, B, C, D, K));
}
}
|
Javascript
<script>
const fourSumLessThanK = (A, B, C, D, K) => {
let merge1 = [];
let merge2 = [];
let res = 0;
for (let i in A) {
for (let j in B) {
merge1.push(A[i] + B[j]);
}
}
for (let i in C) {
for (let j in D) {
merge2.push(C[i] + D[j]);
}
}
merge2.sort();
for (let i in merge1) {
let l = 0, r = merge2.length - 1;
let pos = -1;
while (l <= r) {
let mid = l + parseInt((r - l) / 2);
if (merge2[mid] + merge1[i] <= K) {
pos = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
res += pos + 1;
}
return res;
}
let A = [2, 3];
let B = [5, 2];
let C = [0];
let D = [1, 2];
let K = 6;
document.write(fourSumLessThanK(A, B, C, D, K));
</script>
|
Time Complexity: O(N2 * logN)
Auxiliary Space: O(N2)
Using recursive function:
Approach:
- Define a recursive function named count_combinations that takes five arguments: A, B, C, D, and K, where A, B, C, D are lists of integers, and K is an integer.The function also has two optional arguments: i and current_sum, which are initialized to 0.
- The base case of the recursive function is when i is equal to 4, which means we have chosen one element from each of the four lists.
- In the base case, the function checks if the sum of the four chosen elements is less than or equal to K. If it is, the function returns 1, indicating that we have found a valid combination.
- Otherwise, the function returns 0.
- In the recursive case, the function initializes a variable named count to 0.
- The function then iterates over the i-th list (i.e., A if i is 0, B if i is 1, etc.) and recursively calls
- count_combinations with the next index, i+1, and the updated current_sum equal to current_sum + num, where num is the current element from the list.
- The function adds the result of the recursive call to count.
- After iterating over all the elements in the i-th list, the function returns count.
C++
#include <iostream>
#include <vector>
using namespace std;
int countCombinations(vector< int >& A, vector< int >& B, vector< int >& C, vector< int >& D, int K, int i, int currentSum) {
if (i == 4) {
return currentSum <= K ? 1 : 0;
}
int count = 0;
vector< int > currentArray;
if (i == 0) {
currentArray = A;
} else if (i == 1) {
currentArray = B;
} else if (i == 2) {
currentArray = C;
} else {
currentArray = D;
}
for ( int num : currentArray) {
count += countCombinations(A, B, C, D, K, i + 1, currentSum + num);
}
return count;
}
int main() {
vector< int > A = {2, 3};
vector< int > B = {5, 2};
vector< int > C = {0};
vector< int > D = {1, 2};
int K = 6;
int count = countCombinations(A, B, C, D, K, 0, 0);
cout << count << endl;
return 0;
}
|
Java
public class CountCombinations {
public static int countCombinations( int [] A, int [] B, int [] C,
int [] D, int K, int i,
int currentSum) {
if (i == 4 ) {
return currentSum <= K ? 1 : 0 ;
}
int count = 0 ;
int [] currentArray = i == 0 ? A : (i == 1 ? B : (i == 2 ? C : D));
for ( int num : currentArray) {
count += countCombinations(A, B, C, D, K, i + 1 , currentSum + num);
}
return count;
}
public static void main(String[] args) {
int [] A = { 2 , 3 };
int [] B = { 5 , 2 };
int [] C = { 0 };
int [] D = { 1 , 2 };
int K = 6 ;
int count = countCombinations(A, B, C, D, K, 0 , 0 );
System.out.println(count);
}
}
|
Python3
def count_combinations(A, B, C, D, K, i = 0 , current_sum = 0 ):
if i = = 4 :
return int (current_sum < = K)
count = 0
for num in [A, B, C, D][i]:
count + = count_combinations(A, B, C, D, K, i + 1 , current_sum + num)
return count
A = [ 2 , 3 ]
B = [ 5 , 2 ]
C = [ 0 ]
D = [ 1 , 2 ]
K = 6
count = count_combinations(A, B, C, D, K)
print (count)
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int CountCombinations(List< int > A, List< int > B, List< int > C, List< int > D, int K, int i, int currentSum)
{
if (i == 4)
{
return currentSum <= K ? 1 : 0;
}
int count = 0;
List< int > currentArray = new List< int >();
if (i == 0)
{
currentArray = A;
}
else if (i == 1)
{
currentArray = B;
}
else if (i == 2)
{
currentArray = C;
}
else
{
currentArray = D;
}
foreach ( int num in currentArray)
{
count += CountCombinations(A, B, C, D, K, i + 1, currentSum + num);
}
return count;
}
static void Main()
{
List< int > A = new List< int > { 2, 3 };
List< int > B = new List< int > { 5, 2 };
List< int > C = new List< int > { 0 };
List< int > D = new List< int > { 1, 2 };
int K = 6;
int count = CountCombinations(A, B, C, D, K, 0, 0);
Console.WriteLine(count);
}
}
|
Javascript
function countCombinations(A, B, C, D, K, i, currentSum) {
if (i === 4) {
return currentSum <= K ? 1 : 0;
}
let count = 0;
let currentArray = [];
if (i === 0) {
currentArray = A;
} else if (i === 1) {
currentArray = B;
} else if (i === 2) {
currentArray = C;
} else {
currentArray = D;
}
for (let num of currentArray) {
count += countCombinations(A, B, C, D, K, i + 1, currentSum + num);
}
return count;
}
function main() {
const A = [2, 3];
const B = [5, 2];
const C = [0];
const D = [1, 2];
const K = 6;
const count = countCombinations(A, B, C, D, K, 0, 0);
console.log( "Number of combinations: " + count);
}
main();
|
Time complexity: O(4^n), where n is the maximum length of the input arrays.
Space complexity: O(n) (recursion depth)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...