Skip to content
Related Articles

Related Articles

Improve Article

Sum of subsets nearest to K possible from two given arrays

  • Last Updated : 13 May, 2021

Given two arrays A[] and B[] consisting of N and M integers respectively, and an integer K, the task is to find the sum nearest to K possible by selecting exactly one element from the array A[] and an element from the array B[], at most twice.

Examples:

Input: A[] = {1, 7}, B[] = {3, 4}, K = 10
Output: 10
Explanation:
Sum obtained by selecting A[0] and A[1] = 3 + 7 = 10, which is closest to the value K(= 10).

Input: A[] = {2, 3}, B[] = {4, 5, 30}, K = 18
Output: 17

Approach: The given problem can be solved by using recursion, by finding the sum of elements of the subsets of the array B[] having sum closest to (K – A[i]) for each array element A[i]. Follow the steps below to solve the problem:



  • Initialize two variables, say mini as INT_MAX and ans as INT_MAX to store the minimum absolute difference and the value closest to K.
  • Define a recursive function, say findClosest(arr, i, currSum) to find the subset-sum of the array closest to K, where i is the index in the array B[] and currSum stores the sum of the subset.
    • If the value of i is at least M, then return from the function.
    • If the absolute value of (currSum – K) is less than mini, then update the value of mini as abs(currSum – K) and update the value of ans as currSum.
    • If the absolute value of (currSum – K) is equal to mini then, update the value of ans as the minimum of ans and currSum.
    • Call the recursive function excluding the element B[i] as findClosest(i + 1, currSum).
    • Call the recursive function including the element B[i] once as findClosest(i + 1, currSum + B[i]).
    • Call the recursive function including the element B[i] twice as findClosest(i + 1, currSum + 2*B[i]).
  • Traverse the given array A[] and for every element call the function findClosest(0, A[i]).
  • After completing the above steps, print the value of ans as the resultant sum.

Below is the implementation of the above approach:

C++




// C++ program of the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Stores the sum closest to K
int ans = INT_MAX;
 
// Stores the minimum absolute difference
int mini = INT_MAX;
 
// Function to choose the elements
// from the array B[]
void findClosestTarget(int i, int curr,
                       int B[], int M,
                       int K)
{
 
    // If absolute difference is less
    // then minimum value
    if (abs(curr - K) < mini) {
 
        // Update the minimum value
        mini = abs(curr - K);
 
        // Update the value of ans
        ans = curr;
    }
 
    // If absolute difference between
    // curr and K is equal to minimum
    if (abs(curr - K) == mini) {
 
        // Update the value of ans
        ans = min(ans, curr);
    }
 
    // If i is greater than M - 1
    if (i >= M)
        return;
 
    // Includes the element B[i] once
    findClosestTarget(i + 1, curr + B[i],
                      B, M, K);
 
    // Includes the element B[i] twice
    findClosestTarget(i + 1, curr + 2 * B[i],
                      B, M, K);
 
    // Excludes the element B[i]
    findClosestTarget(i + 1, curr, B, M, K);
}
 
// Function to find a subset sum
// whose sum is closest to K
int findClosest(int A[], int B[],
                int N, int M, int K)
{
    // Traverse the array A[]
    for (int i = 0; i < N; i++) {
 
        // Function Call
        findClosestTarget(0, A[i], B,
                          M, K);
    }
 
    // Return the ans
    return ans;
}
 
// Driver Code
int main()
{
    // Input
    int A[] = { 2, 3 };
    int B[] = { 4, 5, 30 };
    int N = sizeof(A) / sizeof(A[0]);
    int M = sizeof(B) / sizeof(B[0]);
    int K = 18;
 
    // Function Call
    cout << findClosest(A, B, N, M, K);
 
    return 0;
}

Java




// java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
public class GFG {
 
    // Stores the sum closest to K
    static int ans = Integer.MAX_VALUE;
 
    // Stores the minimum absolute difference
    static int mini = Integer.MAX_VALUE;
 
    // Function to choose the elements
    // from the array B[]
    static void findClosestTarget(int i, int curr, int B[],
                                  int M, int K)
    {
 
        // If absolute difference is less
        // then minimum value
        if (Math.abs(curr - K) < mini) {
 
            // Update the minimum value
            mini = Math.abs(curr - K);
 
            // Update the value of ans
            ans = curr;
        }
 
        // If absolute difference between
        // curr and K is equal to minimum
        if (Math.abs(curr - K) == mini) {
 
            // Update the value of ans
            ans = Math.min(ans, curr);
        }
 
        // If i is greater than M - 1
        if (i >= M)
            return;
 
        // Includes the element B[i] once
        findClosestTarget(i + 1, curr + B[i], B, M, K);
 
        // Includes the element B[i] twice
        findClosestTarget(i + 1, curr + 2 * B[i], B, M, K);
 
        // Excludes the element B[i]
        findClosestTarget(i + 1, curr, B, M, K);
    }
 
    // Function to find a subset sum
    // whose sum is closest to K
    static int findClosest(int A[], int B[], int N, int M,
                           int K)
    {
        // Traverse the array A[]
        for (int i = 0; i < N; i++) {
 
            // Function Call
            findClosestTarget(0, A[i], B, M, K);
        }
 
        // Return the ans
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
 
        // Input
        int A[] = { 2, 3 };
        int B[] = { 4, 5, 30 };
        int N = A.length;
        int M = B.length;
        int K = 18;
 
        // Function Call
        System.out.print(findClosest(A, B, N, M, K));
    }
}
 
// This code is contributed by Kingash.

Python3




# Python3 program of the above approach
 
# Stores the sum closest to K
ans = 10**8
 
# Stores the minimum absolute difference
mini = 10**8
 
# Function to choose the elements
# from the array B[]
def findClosestTarget(i, curr, B, M, K):
    global ans, mini
     
    # If absolute difference is less
    # then minimum value
    if (abs(curr - K) < mini):
 
        # Update the minimum value
        mini = abs(curr - K)
 
        # Update the value of ans
        ans = curr
 
    # If absolute difference between
    # curr and K is equal to minimum
    if (abs(curr - K) == mini):
       
        # Update the value of ans
        ans = min(ans, curr)
 
    # If i is greater than M - 1
    if (i >= M):
        return
 
    # Includes the element B[i] once
    findClosestTarget(i + 1, curr + B[i], B, M, K)
 
    # Includes the element B[i] twice
    findClosestTarget(i + 1, curr + 2 * B[i], B, M, K)
 
    # Excludes the element B[i]
    findClosestTarget(i + 1, curr, B, M, K)
 
# Function to find a subset sum
# whose sum is closest to K
def findClosest(A, B, N, M, K):
   
    # Traverse the array A[]
    for i in range(N):
       
        # Function Call
        findClosestTarget(0, A[i], B, M, K)
 
    # Return the ans
    return ans
 
# Driver Code
if __name__ == '__main__':
   
    # Input
    A = [2, 3]
    B = [4, 5, 30]
    N = len(A)
    M = len(B)
    K = 18
 
    # Function Call
    print (findClosest(A, B, N, M, K))
 
# This code is contributed by mohit kumar 29.

C#




// C# program of the above approach
using System;
class GFG
{
   
    // Stores the sum closest to K
    static int ans = Int32.MaxValue;
 
    // Stores the minimum absolute difference
    static int mini = Int32.MaxValue;
 
    // Function to choose the elements
    // from the array B[]
    static void findClosestTarget(int i, int curr, int[] B,
                                  int M, int K)
    {
 
        // If absolute difference is less
        // then minimum value
        if (Math.Abs(curr - K) < mini) {
 
            // Update the minimum value
            mini = Math.Abs(curr - K);
 
            // Update the value of ans
            ans = curr;
        }
 
        // If absolute difference between
        // curr and K is equal to minimum
        if (Math.Abs(curr - K) == mini) {
 
            // Update the value of ans
            ans = Math.Min(ans, curr);
        }
 
        // If i is greater than M - 1
        if (i >= M)
            return;
 
        // Includes the element B[i] once
        findClosestTarget(i + 1, curr + B[i], B, M, K);
 
        // Includes the element B[i] twice
        findClosestTarget(i + 1, curr + 2 * B[i], B, M, K);
 
        // Excludes the element B[i]
        findClosestTarget(i + 1, curr, B, M, K);
    }
 
    // Function to find a subset sum
    // whose sum is closest to K
    static int findClosest(int[] A, int[] B, int N, int M,
                           int K)
    {
       
        // Traverse the array A[]
        for (int i = 0; i < N; i++) {
 
            // Function Call
            findClosestTarget(0, A[i], B, M, K);
        }
 
        // Return the ans
        return ans;
    }
 
    // Driver Code
    public static void Main()
    {
        // Input
        int[] A = { 2, 3 };
        int[] B = { 4, 5, 30 };
        int N = A.Length;
        int M = B.Length;
        int K = 18;
 
        // Function Call
        Console.WriteLine(findClosest(A, B, N, M, K));
    }
}
 
// This code is contributed by ukasp.

Javascript




<script>
        // Javascript program for the above approach
 
        // Stores the sum closest to K
        let ans = Number.MAX_SAFE_INTEGER
 
        // Stores the minimum absolute difference
        let mini = Number.MAX_SAFE_INTEGER
 
        // Function to choose the elements
        // from the array B[]
        function findClosestTarget(i, curr, B,
            M, K) {
 
            // If absolute difference is less
            // then minimum value
            if (Math.abs(curr - K) < mini) {
                // Update the minimum value
                mini = Math.abs(curr - K);
 
                // Update the value of ans
                ans = curr;
            }
 
            // If absolute difference between
            // curr and K is equal to minimum
            if (Math.abs(curr - K) == mini) {
 
                // Update the value of ans
                ans = Math.min(ans, curr);
            }
 
            // If i is greater than M - 1
            if (i >= M)
                return;
 
            // Includes the element B[i] once
            findClosestTarget(i + 1, curr + B[i], B, M, K);
 
            // Includes the element B[i] twice
            findClosestTarget(i + 1, curr + 2 * B[i], B, M, K);
 
            // Excludes the element B[i]
            findClosestTarget(i + 1, curr, B, M, K);
        }
 
        // Function to find a subset sum
        // whose sum is closest to K
        function findClosest(A, B, N, M, K) {
            // Traverse the array A[]
            for (let i = 0; i < N; i++) {
 
                // Function Call
                findClosestTarget(0, A[i], B, M, K);
            }
 
            // Return the ans
            return ans;
        }
 
        // Driver Code
        // Input
        let A = [2, 3];
        let B = [4, 5, 30];
        let N = A.length;
        let M = B.length;
        let K = 18;
 
        // Function Call
        document.write(findClosest(A, B, N, M, K));
         
        //This code is contributed by Hritik.
    </script>
Output: 
17

 

Time Complexity: O(N * 3M)
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :