Given three integers n, k, target, and an array of coins[] of size n. Find if it is possible to make a change of target cents by using an infinite supply of each coin but the total number of coins used must be exactly equal to k.
Examples:
Input: n = 5, k = 3, target = 11, coins = {1, 10, 5, 8, 6}
Output:Â 1
Explanation: 2 coins of 5 and 1 coin of 1 can be used to make a change of 11 i.e. 11 => 5 + 5 + 1.Input:Â n = 3, k = 5, target = 25, coins = {7, 2, 4}
Output:Â 1
Explanation:Â 3 coins 7, 2 coins of 2 can be used to make a change of 25 i.e. 25 => 7+7+7+2+2.
Naive Approach :
The basic way to solve this problem is to generate all possible combinations by using a recursive approach.
Below are the steps involved in the implementation of the code:
- If target == 0 and k == 0, return true
- If n == 0 or target < 0 or k < 0, return falseÂ
- Otherwise, the result is true if either of the following conditions is satisfied:
- Include the last coin and recursively check if it is possible to make the remaining target using k-1 coins.
- Exclude the last coin and recursively check if it is possible to make the target using the remaining n-1 coins and k coins.
below is the code implementation of the above code:
C++
#include <bits/stdc++.h> using namespace std; Â
// Function to check if it is possible to make a change of // target cents using exactly k coins from the given coins // array of size n bool canMakeChange( int target, int k, int coins[], int n) {     // If target and k are both 0, then we have found a     // valid combination of coins     if (target == 0 && k == 0) {         return true ;     }     // If n becomes 0 or target or k becomes negative, then     // the current combination of coins is not valid     if (n == 0 || target < 0 || k < 0) {         return false ;     }     // we can either include the current coin or exclude it     // We check if it is possible to make the change by     // including the current coin or excluding it     return canMakeChange(target - coins[n - 1], k - 1,                          coins, n)            || canMakeChange(target, k, coins, n - 1); } Â
int main() { Â Â Â Â int n = 5; Â Â Â Â int k = 3; Â Â Â Â int target = 11; Â Â Â Â int coins[] = { 1, 10, 5, 8, 6 }; Â
    // Check if it is possible to make the change using 'k'     // coins from the 'coins' array to get 'target' cents     bool result = canMakeChange(target, k, coins, n); Â
    // Print the result     if (result) {         cout << "1" << endl;     }     else {         cout << "0" << endl;     }     return 0; } |
Java
import java.util.Arrays; Â
class GFG {          // Function to check if it is possible to make a change of     // target cents using exactly k coins from the given coins     // array of size n     static boolean canMakeChange( int target, int k, int [] coins, int n) {         // If target and k are both 0, then we have found a         // valid combination of coins         if (target == 0 && k == 0 ) {             return true ;         }         // If n becomes 0 or target or k becomes negative, then         // the current combination of coins is not valid         if (n == 0 || target < 0 || k < 0 ) {             return false ;         }         // we can either include the current coin or exclude it         // We check if it is possible to make the change by         // including the current coin or excluding it         return canMakeChange(target - coins[n - 1 ], k - 1 , coins, n)                 || canMakeChange(target, k, coins, n - 1 );     }          public static void main(String[] args) {         int n = 5 ;         int k = 3 ;         int target = 11 ;         int [] coins = { 1 , 10 , 5 , 8 , 6 }; Â
        // Check if it is possible to make the change using 'k'         // coins from the 'coins' array to get 'target' cents         boolean result = canMakeChange(target, k, coins, n); Â
        // Print the result         if (result) {             System.out.println( "1" );         } else {             System.out.println( "0" );         }     } } Â
// This code is contributed by shivamgupta0987654321 |
Python3
# python Implementation Â
# Function to check if it is possible to make a change of # target cents using exactly k coins from the given coins # array of size n def can_make_change(target, k, coins, n):     # If target and k are both 0, then we have found a     # valid combination of coins     if target = = 0 and k = = 0 :         return True     # If n becomes 0 or target or k becomes negative, then     # the current combination of coins is not valid     if n = = 0 or target < 0 or k < 0 :         return False     # we can either include the current coin or exclude it     # We check if it is possible to make the change by     # including the current coin or excluding it     return can_make_change(target - coins[n - 1 ], k - 1 , coins, n) or can_make_change(target, k, coins, n - 1 ) Â
def main(): Â Â Â Â n = 5 Â Â Â Â k = 3 Â Â Â Â target = 11 Â Â Â Â coins = [ 1 , 10 , 5 , 8 , 6 ] Â
    # Check if it is possible to make the change using 'k'     # coins from the 'coins' array to get 'target' cents     result = can_make_change(target, k, coins, n) Â
    # Print the result     if result:         print ( "1" )     else :         print ( "0" ) Â
if __name__ = = "__main__" : Â Â Â Â main() |
C#
// C# Implementation using System; Â
class GFG {      // Function to check if it is possible to make a change of // target cents using exactly k coins from the given coins // array of size n static bool canMakeChange( int target, int k, int [] coins, int n) {     // If target and k are both 0, then we have found a     // valid combination of coins     if (target == 0 && k == 0) {         return true ;     }     // If n becomes 0 or target or k becomes negative, then     // the current combination of coins is not valid     if (n == 0 || target < 0 || k < 0) {         return false ;     }     // we can either include the current coin or exclude it     // We check if it is possible to make the change by     // including the current coin or excluding it     return canMakeChange(target - coins[n - 1], k - 1,                         coins, n)         || canMakeChange(target, k, coins, n - 1); } Â
public static int Main() { Â Â Â Â int n = 5; Â Â Â Â int k = 3; Â Â Â Â int target = 11; Â Â Â Â int [] coins = { 1, 10, 5, 8, 6 }; Â
    // Check if it is possible to make the change using 'k'     // coins from the 'coins' array to get 'target' cents     bool result = canMakeChange(target, k, coins, n); Â
    // Print the result     if (result) {         Console.WriteLine( "1" );     }     else {         Console.WriteLine( "0" );     }     return 0; } Â
} Â
// This code is contributed by Utkarsh Kumar |
Javascript
// JavaScript Implementation Â
// Function to check if it is possible to make a change of // target cents using exactly k coins from the given coins // array of size n function can_make_change(target, k, coins, n) {     // If target and k are both 0, then we have found a     // valid combination of coins     if (target === 0 && k === 0) {         return true ;     }     // If n becomes 0 or target or k becomes negative, then     // the current combination of coins is not valid     if (n === 0 || target < 0 || k < 0) {         return false ;     }     // we can either include the current coin or exclude it     // We check if it is possible to make the change by     // including the current coin or excluding it     return can_make_change(target - coins[n - 1], k - 1, coins, n) || can_make_change(target, k, coins, n - 1); } Â
let n = 5; let k = 3; let target = 11; let coins = [1, 10, 5, 8, 6]; Â
// Check if it is possible to make the change using 'k' // coins from the 'coins' array to get 'target' cents let result = can_make_change(target, k, coins, n); Â
// Print the result if (result) { Â Â Â Â console.log( "1" ); } else { Â Â Â Â console.log( "0" ); } Â
// This code is contributed by Tapesh(tapeshdua420) |
1
Time Complexity : O(2^(k+n))
Space Complexity : Â O(k+n)
Efficient Approach: This can be solved with the following idea:
The approach used is a dynamic programming approach, The approach works by building a table of subproblems using a two-dimensional boolean array. The approach iterates over all values of i from 1 to target and all values of j from 0 to K. For each subproblem dp[i][j], the algorithm checks whether any of the coins in the array can be used to add up to i while using j-1 coins to add up to the remaining value. If so, the subproblem is marked as solved by setting dp[i][j] = true. The algorithm returns dp[target][K] as the solution to the original problem.Â
Below are the steps involved in the implementation of the code:
- Initialize a two-dimensional boolean array dp of size (target+1) x (K+1).
- Set the base case dp[0][0] = true.
- For i from 1 to target and j from 0 to K, do the following:
- For each coin in the array coins, do the following:
- If the current coin denomination is less than or equal to i, and j > 0 (i.e., there are still coins remaining to be used), and dp[i-coin][j-1] is true, then set dp[i][j] to true and break out of the loop over coins.
- For each coin in the array coins, do the following:
- Return dp[target][K] as the solution to the original problem.
below is the code implementation of the above code:
C++
// Nikunj Sonigara Â
#include <bits/stdc++.h> using namespace std; Â
// Function to check whether target can be achieved by K coins bool makeChanges( int N, int K, int target, vector< int >& coins) { Â Â Â Â vector<vector< bool >> dp(target + 1, vector< bool >(K + 1, false )); Â Â Â Â dp[0][0] = true ; Â
    for ( int i = 1; i <= target; i++) {         for ( int j = 0; j <= K; j++) {             for ( int coin : coins) {                 if (coin <= i && j > 0 && dp[i - coin][j - 1]) {                     dp[i][j] = true ;                     break ;                 }             }         }     } Â
    // Return the result     return dp[target][K]; } Â
int main() { Â Â Â Â int N = 5; Â Â Â Â int K = 3; Â Â Â Â int target = 11; Â Â Â Â vector< int > coins = {1, 10, 5, 8, 6}; Â
    // Function call     bool result = makeChanges(N, K, target, coins);     if (result) {         cout << '1' << endl;     } else {         cout << '0' << endl;     } Â
    return 0; } |
Java
// java code for the above approach: import java.util.*; Â
public class CoinChangeProblem { Â
    // Function to check whether target     // can be achieved by K coins     public static boolean     makeChanges( int N, int K, int target, int [] coins)     {         boolean [][] dp = new boolean [target + 1 ][K + 1 ];         dp[ 0 ][ 0 ] = true ; Â
        for ( int i = 1 ; i <= target; i++) {             for ( int j = 0 ; j <= K; j++) {                 for ( int coin : coins) {                     if (coin <= i && j > 0                         && dp[i - coin][j - 1 ]) {                         dp[i][j] = true ;                         break ;                     }                 }             }         } Â
        // Return the result         return dp[target][K];     } Â
    // Driver codes     public static void main(String[] args)     {         int N = 5 ;         int K = 3 ;         int target = 11 ;         int [] coins = { 1 , 10 , 5 , 8 , 6 }; Â
        // Function call         boolean result = makeChanges(N, K, target, coins);         if (result == true ) {             System.out.println( '1' );         }         else {             System.out.println( '0' );         }     } } |
Python
# Nikunj Sonigara Â
def make_changes(N, K, target, coins): Â Â Â Â dp = [[ False for _ in range (K + 1 )] for _ in range (target + 1 )] Â Â Â Â dp[ 0 ][ 0 ] = True Â
    for i in range ( 1 , target + 1 ):         for j in range (K + 1 ):             for coin in coins:                 if coin < = i and j > 0 and dp[i - coin][j - 1 ]:                     dp[i][j] = True                     break Â
    # Return the result     return dp[target][K] Â
N = 5 K = 3 target = 11 coins = [ 1 , 10 , 5 , 8 , 6 ] Â
# Function call result = make_changes(N, K, target, coins) if result: Â Â Â Â print ( '1' ) else : Â Â Â Â print ( '0' ) |
C#
using System; Â
public class CoinChangeProblem {     // Function to check whether target     // can be achieved by K coins     public static bool MakeChanges( int N, int K, int target, int [] coins)     {         bool [,] dp = new bool [target + 1, K + 1];         dp[0, 0] = true ;         for ( int i = 1; i <= target; i++)         {             for ( int j = 0; j <= K; j++)             {                 foreach ( int coin in coins)                 {                     if (coin <= i && j > 0 && dp[i - coin, j - 1])                     {                         dp[i, j] = true ;                         break ;                     }                 }             }         }         // Return the result         return dp[target, K];     }     // Driver codes     public static void Main( string [] args)     {         int N = 5;         int K = 3;         int target = 11;         int [] coins = { 1, 10, 5, 8, 6 };         // Function call         bool result = MakeChanges(N, K, target, coins);         if (result == true )         {             Console.WriteLine( '1' );         }         else         {             Console.WriteLine( '0' );         }     } } |
Javascript
// Nikunj Sonigara Â
function makeChanges(N, K, target, coins) { Â Â Â Â const dp = new Array(target + 1); Â Â Â Â for (let i = 0; i <= target; i++) { Â Â Â Â Â Â Â Â dp[i] = new Array(K + 1).fill( false ); Â Â Â Â } Â Â Â Â dp[0][0] = true ; Â
    for (let i = 1; i <= target; i++) {         for (let j = 0; j <= K; j++) {             for (const coin of coins) {                 if (coin <= i && j > 0 && dp[i - coin][j - 1]) {                     dp[i][j] = true ;                     break ;                 }             }         }     } Â
    // Return the result     return dp[target][K]; } Â
const N = 5; const K = 3; const target = 11; const coins = [1, 10, 5, 8, 6]; Â
// Function call const result = makeChanges(N, K, target, coins); if (result) { Â Â Â Â console.log( '1' ); } else { Â Â Â Â console.log( '0' ); } |
1
Time Complexity: O(NKT)
Auxiliary Space: O(NKT)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!