You are given a 0-indexed integer array coins
, representing the values of the coins available, and an integer target
.
An integer x
is obtainable if there exists a subsequence of coins
that sums to x
.
Return the minimum number of coins of any value that need to be added to the array so that every integer in the range [1, target]
is obtainable.
A subsequence of an array is a new non-empty array that is formed from the original array by deleting some (possibly none) of the elements without disturbing the relative positions of the remaining elements.
Example 1:
Input: coins = [1,4,10], target = 19 Output: 2 Explanation: We need to add coins 2 and 8. The resulting array will be [1,2,4,8,10]. It can be shown that all integers from 1 to 19 are obtainable from the resulting array, and that 2 is the minimum number of coins that need to be added to the array.
Example 2:
Input: coins = [1,4,10,5,7,19], target = 19 Output: 1 Explanation: We only need to add the coin 2. The resulting array will be [1,2,4,5,7,10,19]. It can be shown that all integers from 1 to 19 are obtainable from the resulting array, and that 1 is the minimum number of coins that need to be added to the array.
Example 3:
Input: coins = [1,1,1], target = 20 Output: 3 Explanation: We need to add coins 4, 8, and 16. The resulting array will be [1,1,1,4,8,16]. It can be shown that all integers from 1 to 20 are obtainable from the resulting array, and that 3 is the minimum number of coins that need to be added to the array.
Constraints:
1 <= target <= 105
1 <= coins.length <= 105
1 <= coins[i] <= target
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute-force method to solve this coin problem involves systematically checking every possible combination of coin additions. We start with the smallest addition and incrementally consider larger additions until we fulfill the required target. This guarantees we'll find the absolute minimum number of coins needed, although it might take a while.
Here's how the algorithm would work step-by-step:
def minimum_number_coins_to_add(coins, target):
coins.sort()
added_coins = 0
reachable_value = 0
while reachable_value < target:
# If we can reach the next coin, extend reachable value.
if not coins or coins[0] > reachable_value + 1:
needed_coin = reachable_value + 1
reachable_value += needed_coin
added_coins += 1
# Otherwise, use one of the given coins.
else:
reachable_value += coins[0]
coins.pop(0)
# Ensure we don't exceed the target in one step.
reachable_value = min(reachable_value, target)
# Sort coins so that we always use the smallest coin.
coins.sort()
# After each addition, check if we've reached target.
if reachable_value >= target:
return added_coins
return added_coins
The problem asks us to find the fewest extra coins to add to an existing set so that we can make change for every amount from 1 to the target amount. The key insight is to sort the coins we already have and then iteratively determine the smallest amount we *cannot* currently make change for. Then we add a coin of that value to our set.
Here's how the algorithm would work step-by-step:
def minimum_coins_to_add(coins, target): coins.sort()
number_of_coins_added = 0
reachable_amount = 0
for coin in coins:
# Add coins to reach values between reachable amount and current coin value
while coin > reachable_amount + 1:
reachable_amount += reachable_amount + 1
number_of_coins_added += 1
# Optimization to prevent infinite loop
if reachable_amount >= target:
return number_of_coins_added
# Update reachable amount
reachable_amount += coin
# Add coins until we can reach the target
while reachable_amount < target:
# We always add one more than what we can reach
number_of_coins_added += 1
reachable_amount += reachable_amount + 1
return number_of_coins_added
Case | How to Handle |
---|---|
Coins array is null or empty | Return 0 if the coins array is null or empty since no coins are available to supplement. |
Target value is less than or equal to zero | Return 0 if the target is non-positive, as we don't need to add any coins. |
Coins array contains negative or zero values | Filter out negative or zero values from the coins array as only positive coin denominations are meaningful and valid. |
Coins array contains a single, large value exceeding target | If the smallest coin exceeds the target, then return 1; otherwise proceed with the algorithm. |
Target can be achieved by the given coins without adding any | If the target is already achievable using the given coins, return 0. |
Target is a large value and the given coins are all small | The algorithm should handle large targets efficiently (e.g., using a greedy approach where possible) without exceeding memory limits or causing integer overflow. |
Integer overflow when calculating the sum of existing coins | Use long or appropriate data types to store the sum to prevent potential overflow when accumulating coin values. |
Maximum sized input array | Consider the time complexity of the algorithm to ensure scalability with large input arrays, such as O(n log n) with sorting or O(n) using a dynamic programming approach. |