Coin change problem with limited coins
Last Updated :
04 Oct, 2023
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;
bool canMakeChange( int target, int k, int coins[], int n)
{
if (target == 0 && k == 0) {
return true ;
}
if (n == 0 || target < 0 || k < 0) {
return false ;
}
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 };
bool result = canMakeChange(target, k, coins, n);
if (result) {
cout << "1" << endl;
}
else {
cout << "0" << endl;
}
return 0;
}
|
Java
import java.util.Arrays;
class GFG {
static boolean canMakeChange( int target, int k, int [] coins, int n) {
if (target == 0 && k == 0 ) {
return true ;
}
if (n == 0 || target < 0 || k < 0 ) {
return false ;
}
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 };
boolean result = canMakeChange(target, k, coins, n);
if (result) {
System.out.println( "1" );
} else {
System.out.println( "0" );
}
}
}
|
Python3
def can_make_change(target, k, coins, n):
if target = = 0 and k = = 0 :
return True
if n = = 0 or target < 0 or k < 0 :
return False
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 ]
result = can_make_change(target, k, coins, n)
if result:
print ( "1" )
else :
print ( "0" )
if __name__ = = "__main__" :
main()
|
C#
using System;
class GFG {
static bool canMakeChange( int target, int k, int [] coins, int n)
{
if (target == 0 && k == 0) {
return true ;
}
if (n == 0 || target < 0 || k < 0) {
return false ;
}
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 };
bool result = canMakeChange(target, k, coins, n);
if (result) {
Console.WriteLine( "1" );
}
else {
Console.WriteLine( "0" );
}
return 0;
}
}
|
Javascript
function can_make_change(target, k, coins, n) {
if (target === 0 && k === 0) {
return true ;
}
if (n === 0 || target < 0 || k < 0) {
return false ;
}
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];
let result = can_make_change(target, k, coins, n);
if (result) {
console.log( "1" );
} else {
console.log( "0" );
}
|
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.
- Return dp[target][K] as the solution to the original problem.
below is the code implementation of the above code:
C++
#include <bits/stdc++.h>
using namespace std;
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 dp[target][K];
}
int main() {
int N = 5;
int K = 3;
int target = 11;
vector< int > coins = {1, 10, 5, 8, 6};
bool result = makeChanges(N, K, target, coins);
if (result) {
cout << '1' << endl;
} else {
cout << '0' << endl;
}
return 0;
}
|
Java
import java.util.*;
public class CoinChangeProblem {
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 dp[target][K];
}
public static void main(String[] args)
{
int N = 5 ;
int K = 3 ;
int target = 11 ;
int [] coins = { 1 , 10 , 5 , 8 , 6 };
boolean result = makeChanges(N, K, target, coins);
if (result == true ) {
System.out.println( '1' );
}
else {
System.out.println( '0' );
}
}
}
|
Python
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 dp[target][K]
N = 5
K = 3
target = 11
coins = [ 1 , 10 , 5 , 8 , 6 ]
result = make_changes(N, K, target, coins)
if result:
print ( '1' )
else :
print ( '0' )
|
C#
using System;
public class CoinChangeProblem
{
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 dp[target, K];
}
public static void Main( string [] args)
{
int N = 5;
int K = 3;
int target = 11;
int [] coins = { 1, 10, 5, 8, 6 };
bool result = MakeChanges(N, K, target, coins);
if (result == true )
{
Console.WriteLine( '1' );
}
else
{
Console.WriteLine( '0' );
}
}
}
|
Javascript
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 dp[target][K];
}
const N = 5;
const K = 3;
const target = 11;
const coins = [1, 10, 5, 8, 6];
const result = makeChanges(N, K, target, coins);
if (result) {
console.log( '1' );
} else {
console.log( '0' );
}
|
Time Complexity: O(NKT)
Auxiliary Space: O(NKT)
Share your thoughts in the comments
Please Login to comment...