Open In App

Sum of subsets nearest to K possible from two given arrays

Last Updated : 13 May, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads