零钱兑换
思路
常见思路为DP,这里采用DFS + 贪心算法:
- 倒排coins数组
- 按照DFS遍历所有组合
由于本题极容易超时,因此在遍历时需要进行大量剪枝等等优化:
- 按照
k = int(remain_amount / reverse_coins[index])计算最多该面值可使用多少硬币,直接从最大值搜索 - 如果现有硬币数超过已查询到的最小组合值,则不再继续查找
代码
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
self.result = float("inf")
def dfs(reverse_coins, remain_amount, index, count):
if remain_amount == 0:
self.result = min(self.result, count)
return
if index == len(reverse_coins):
return
k = int(remain_amount / reverse_coins[index])
while k >= 0 and count + k < self.result:
dfs(reverse_coins, remain_amount - k * reverse_coins[index], index + 1, count + k)
k -= 1
if amount == 0:
return 0
coins.sort(reverse=True)
dfs(coins, amount, 0, 0)
if self.result == float("inf"):
return -1
else:
return self.result