-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Solve LeetCode #518 'Coin Change II' [Medium] using backtracking.
- Loading branch information
1 parent
252b589
commit 4d7c990
Showing
3 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
LeetCode/src/LeetCode.Challenges/CoinChangeII/BacktrackingSolution.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
18
LeetCode/src/LeetCode.Challenges/CoinChangeII/Description.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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` |
65 changes: 65 additions & 0 deletions
65
LeetCode/tests/LeetCode.Challenges.UnitTests/CoinChangeII/BacktrackingSolutionTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; | ||
} | ||
} |