|
| 1 | +""" |
| 2 | +This module finds all possible ways to combine given coin denominations |
| 3 | +to sum up to a specified target amount using a backtracking method. |
| 4 | +
|
| 5 | +The time complexity grows exponentially based on the amount and the set of coins. |
| 6 | +""" |
| 7 | + |
| 8 | +from __future__ import annotations |
| 9 | +from typing import List |
| 10 | + |
| 11 | + |
| 12 | +def inverse_coin_change(amount: int, coins: List[int]) -> List[List[int]]: |
| 13 | + """ |
| 14 | + Computes every possible combination of coins that add up exactly to the target amount. |
| 15 | + Coins can be chosen multiple times. |
| 16 | +
|
| 17 | + :param amount: The total amount to form with the coins. |
| 18 | + :param coins: Available coin denominations. |
| 19 | +
|
| 20 | + Example 1: |
| 21 | + >>> inverse_coin_change(4, [1, 2]) |
| 22 | + [[1, 1, 1, 1], [1, 1, 2], [2, 2]] |
| 23 | +
|
| 24 | + Example 2: |
| 25 | + >>> inverse_coin_change(3, [2]) |
| 26 | + [] |
| 27 | +
|
| 28 | + Example 3: |
| 29 | + >>> inverse_coin_change(0, [1, 2]) |
| 30 | + [[]] |
| 31 | + """ |
| 32 | + results: List[List[int]] = [] |
| 33 | + |
| 34 | + def backtrack(remaining: int, current_combo: List[int], start_index: int) -> None: |
| 35 | + if remaining == 0: |
| 36 | + results.append(current_combo.copy()) |
| 37 | + return |
| 38 | + for i in range(start_index, len(coins)): |
| 39 | + coin = coins[i] |
| 40 | + if coin <= remaining: |
| 41 | + current_combo.append(coin) |
| 42 | + backtrack(remaining - coin, current_combo, i) # Allow coin reuse |
| 43 | + current_combo.pop() |
| 44 | + |
| 45 | + coins.sort() |
| 46 | + backtrack(amount, [], 0) |
| 47 | + return results |
| 48 | + |
| 49 | + |
| 50 | +# Uncomment the lines below to accept user input |
| 51 | +# print("Please enter the target amount:") |
| 52 | +# target_amount = int(input()) |
| 53 | +# print("Enter the coin denominations separated by spaces:") |
| 54 | +# coin_values = list(map(int, input().split())) |
| 55 | +# combinations = inverse_coin_change(target_amount, coin_values) |
| 56 | +# print(combinations) |
| 57 | + |
| 58 | + |
| 59 | +if __name__ == "__main__": |
| 60 | + print("Possible combinations for amount = 4 with coins [1, 2]:") |
| 61 | + print(inverse_coin_change(4, [1, 2])) |
| 62 | + |
| 63 | + print("\nPossible combinations for amount = 5 with coins [1, 3, 5]:") |
| 64 | + print(inverse_coin_change(5, [1, 3, 5])) |
0 commit comments