Open In App

Count of ways to choose 4 unique position elements one from each Array to make sum at most K

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: 

Below is the implementation of the above method.




// C++ to implement the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to get the number of combinations
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) {
 
            // Merging A and B into merge1
            merge1.push_back(i + j);
        }
    }
 
    for (int i : C) {
        for (int j : D) {
 
            // Merging C and D into merge2
            merge2.push_back(i + j);
        }
    }
 
    // Sorting merge2
    sort(merge2.begin(), merge2.end());
 
    // Looping through unsorted merge1
    for (int i : merge1) {
        int l = 0, r = merge2.size() - 1;
        int pos = -1;
 
        // Binary search to find how many
        // Element from merge2 can be paired
        // With merge1 element with sum less
        // Than or equal to K
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (merge2[mid] + i <= K) {
                pos = mid;
                l = mid + 1;
            }
            else {
                r = mid - 1;
            }
        }
 
        // Adding the number
        // Of pairs in the result
        res += pos + 1;
    }
    return res;
}
 
// Driver Code
int main()
{
    vector<int> A = { 2, 3 };
    vector<int> B = { 5, 2 };
    vector<int> C = { 0 };
    vector<int> D = { 1, 2 };
 
    int K = 6;
 
    // Function call
    cout << fourSumLessThanK(A, B, C, D, K);
    return 0;
}




// Java code for the above approach
import java.util.*;
 
class GFG {
 
  // Function to get the number of combinations
  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++) {
 
        // Merging A and B into merge1
        merge1.add(A[i] + B[j]);
      }
    }
 
    for (int i = 0; i < C.length; i++) {
      for (int j = 0; j < D.length; j++) {
 
        // Merging C and D into merge2
        merge2.add(C[i] + D[j]);
      }
    }
 
    // Sorting merge2
    Collections.sort(merge2);
 
    // Looping through unsorted merge1
    for (int i = 0; i < merge1.size(); i++) {
      int l = 0, r = merge2.size() - 1;
      int pos = -1;
 
      // Binary search to find how many
      // Element from merge2 can be paired
      // With merge1 element with sum less
      // Than or equal to K
      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;
        }
      }
 
      // Adding the number
      // Of pairs in the result
      res += pos + 1;
    }
    return res;
  }
 
  // Driver Code
  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));
  }
}
 
// This code is contributed by hrithikgarg03188.




# Python code for the above approach
 
# Function to get the number of combinations
def fourSumLessThanK(A, B, C, D, K):
    merge1=[];
    merge2=[];
    res = 0;
    for i in range(len(A)):
        for j in range(len(B)):
 
            # Merging A and B into merge1
            merge1.append(A[i] + B[j]);
         
    for i in range(len(C)):
        for j in range(len(D)):
 
            # Merging C and D into merge2
            merge2.append(C[i] + D[j]);
      
    # Sorting merge2
    merge2.sort()
 
    # Looping through unsorted merge1
    for i in range(len(merge1)):
        = 0;
        r = len(merge2) - 1;
        pos = -1;
 
        # Binary search to find how many
        # Element from merge2 can be paired
        # With merge1 element with sum less
        # Than or equal to K
        while (l <= r):
            mid = (l +r) // 2;
            if (merge2[mid] + merge1[i] <= K):
                pos = mid;
                l = mid + 1;
             
            else:
                r = mid - 1;
           
        # Adding the number
        # Of pairs in the result
        res = res + pos + 1;
     
    return res;
 
# Driver Code
A = [ 2, 3 ];
B = [ 5, 2 ];
C = [ 0 ];
D = [ 1, 2 ];
 
K = 6;
 
    # Function call
print(fourSumLessThanK(A, B, C, D, K));
  
# This code is contributed by Potta Lokesh




// C# code for the above approach
using System;
using System.Collections;
 
class GFG {
 
  // Function to get the number of combinations
  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++) {
 
        // Merging A and B into merge1
        merge1.Add(A[i] + B[j]);
      }
    }
 
    for (int i = 0; i < C.Length; i++) {
      for (int j = 0; j < D.Length; j++) {
 
        // Merging C and D into merge2
        merge2.Add(C[i] + D[j]);
      }
    }
 
    // Sorting merge2
    merge2.Sort();
 
    // Looping through unsorted merge1
    for (int i = 0; i < merge1.Count; i++) {
      int l = 0, r = merge2.Count - 1;
      int pos = -1;
 
      // Binary search to find how many
      // Element from merge2 can be paired
      // With merge1 element with sum less
      // Than or equal to K
      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;
        }
      }
 
      // Adding the number
      // Of pairs in the result
      res += pos + 1;
    }
    return res;
  }
 
  // Driver Code
  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));
  }
}
 
// This code is contributed by Samim Hossain Mondal.




<script>
    // JavaScript to implement the above approach
 
    // Function to get the number of combinations
    const fourSumLessThanK = (A, B, C, D, K) => {
        let merge1 = [];
        let merge2 = [];
        let res = 0;
        for (let i in A) {
            for (let j in B) {
 
                // Merging A and B into merge1
                merge1.push(A[i] + B[j]);
            }
        }
 
        for (let i in C) {
            for (let j in D) {
 
                // Merging C and D into merge2
                merge2.push(C[i] + D[j]);
            }
        }
 
        // Sorting merge2
        merge2.sort();
 
        // Looping through unsorted merge1
        for (let i in merge1) {
            let l = 0, r = merge2.length - 1;
            let pos = -1;
 
            // Binary search to find how many
            // Element from merge2 can be paired
            // With merge1 element with sum less
            // Than or equal to K
            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;
                }
            }
 
            // Adding the number
            // Of pairs in the result
            res += pos + 1;
        }
        return res;
    }
 
    // Driver Code
    let A = [2, 3];
    let B = [5, 2];
    let C = [0];
    let D = [1, 2];
 
    let K = 6;
 
    // Function call
    document.write(fourSumLessThanK(A, B, C, D, K));
 
    // This code is contributed by rakeshsahni
 
</script>

Output
3






Time Complexity: O(N2 * logN)
Auxiliary Space: O(N2)

 Using recursive function:

Approach:




#include <iostream>
#include <vector>
 
using namespace std;
 
// Function to count combinations
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;
     
    // Choose the current array based on the value of 'i'
    if (i == 0) {
        currentArray = A;
    } else if (i == 1) {
        currentArray = B;
    } else if (i == 2) {
        currentArray = C;
    } else {
        currentArray = D;
    }
 
    // Iterate through the elements of the current array
    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;
}




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);
    }
}




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)




using System;
using System.Collections.Generic;
 
class Program
{
    // Function to count combinations
    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>();
 
        // Choose the current array based on the value of 'i'
        if (i == 0)
        {
            currentArray = A;
        }
        else if (i == 1)
        {
            currentArray = B;
        }
        else if (i == 2)
        {
            currentArray = C;
        }
        else
        {
            currentArray = D;
        }
 
        // Iterate through the elements of the current array
        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);
    }
}




// Recursive function to count combinations
function countCombinations(A, B, C, D, K, i, currentSum) {
    // If we've considered all 4 arrays, check if the current sum is within the limit
    if (i === 4) {
        return currentSum <= K ? 1 : 0;
    }
 
    let count = 0;
    let currentArray = [];
 
    // Choose the current array based on the value of 'i'
    if (i === 0) {
        currentArray = A;
    } else if (i === 1) {
        currentArray = B;
    } else if (i === 2) {
        currentArray = C;
    } else {
        currentArray = D;
    }
 
    // Iterate through the elements of the current array
    for (let num of currentArray) {
        // Recursively explore combinations by moving to the next array and updating the sum
        count += countCombinations(A, B, C, D, K, i + 1, currentSum + num);
    }
 
    return count;
}
 
// Main function
function main() {
    // Define arrays A, B, C, and D, and the value K
    const A = [2, 3];
    const B = [5, 2];
    const C = [0];
    const D = [1, 2];
    const K = 6;
 
    // Call the countCombinations function to start the calculation
    const count = countCombinations(A, B, C, D, K, 0, 0);
 
    // Output the count of combinations
    console.log("Number of combinations: " + count);
}
 
// Call the main function to start the calculation
main();

Output
3






Time complexity: O(4^n), where n is the maximum length of the input arrays.
Space complexity: O(n) (recursion depth)


Article Tags :