Skip to content

Commit

Permalink
Solve LeetCode #518 'Coin Change II' [Medium] using backtracking.
Browse files Browse the repository at this point in the history
  • Loading branch information
eminencegrs committed Dec 13, 2024
1 parent 252b589 commit 4d7c990
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace LeetCode.Challenges.CoinChangeII;

public static class BacktrackingSolution
{
public static int CoinChange(int[] coins, int amount)
{
// Counter to store the total number of combinations
var count = 0;
Backtrack(0, amount);
return count;

void Backtrack(int start, int remaining)
{
// Base Case: if the remaining amount is 0, we have found a valid combination.
if (remaining == 0)
{
count++;
return;
}

// If the remaining amount is negative, this path is invalid.
if (remaining < 0)
{
return;
}

// Iterate through the coins, starting from the current index.
for (var i = start; i < coins.Length; i++)
{
// Include the current coin and recurse.
// 'i' ensures we can reuse the current coin.
Backtrack(i, remaining - coins[i]);
}
}
}
}
18 changes: 18 additions & 0 deletions LeetCode/src/LeetCode.Challenges/CoinChangeII/Description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Coin Change

You are given an integer array `coins` representing coins of different denominations
and an integer `amount` representing a total amount of money.
Return the number, in how many ways you can make the target amount.

You may assume that you have an infinite number of each kind of coin.

## Examples

### Example 1:

Input: `coins = [1,2]`, `amount = 5`
Output: `3`
Explanation:
`5 = 1 + 2 + 2`
`5 = 1 + 1 + 1 + 2`
`5 = 1 + 1 + 1 + 1 + 1`
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using LeetCode.Challenges.CoinChangeII;
using Xunit;
using Shouldly;

namespace LeetCode.Challenges.UnitTests.CoinChangeII;

public class BacktrackingSolutionTests
{
[Theory]
[MemberData(nameof(CoinChangeTestCases))]
public void GivenCoins_WhenCoinChange_ThenResultAsExpected(int[] coins, int amount, int expected)
{
BacktrackingSolution.CoinChange(coins, amount).ShouldBe(expected);
}

public static IEnumerable<object[]> CoinChangeTestCases()
{
// (5)
// / \
// -1 (4) -2 (3)
// / \ \
// -1 (3) -2 (2) -2 (1)
// / \ | |
// -1 (2) -2 (0) (0) (X)
// / \
// -1 (1) -2 (X)
// /
// (0)
//
// Valid Paths:
// [1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 2, 2]
yield return [new[] { 1, 2 }, 5, 3];

// (5)
// / | \
// -1 (4) -2 (3) -5 (0)
// / | |
// -1 (3) -2 (2) -2 (1)
// / | | |
// -1 (2)-2 (0) (0) (X)
// / |
// -1 (1)-2 (X)
// /
// (0)
//
// Valid Paths:
// [1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 2, 2], [5]
yield return [new[] { 1, 2, 5 }, 5, 4];

yield return [new[] { 2 }, 3, 0];
yield return [new[] { 1, 3, 4 }, 6, 4];
yield return [new[] { 5 }, 5, 1];
yield return [new[] { 5 }, 2, 0];
yield return [new[] { 2, 5, 10 }, 1, 0];
yield return [new[] { 10, 5 }, 20, 3];
yield return [new[] { 1, 5, 10, 25 }, 30, 18];
yield return [new[] { 2, 3 }, 7, 1];
yield return [new[] { 1, 2, 5 }, 100, 541];
yield return [new[] { 7, 3, 2 }, 8, 2];
yield return [new[] { 1, 7, 10 }, 14, 4];
yield return [new[] { 1, 3, 4, 7 }, 15, 22];
yield return [new[] { 25, 50, 100 }, 30, 0];
yield return [new[] { 9, 6, 5, 1 }, 11, 6];
}
}

0 comments on commit 4d7c990

Please sign in to comment.