leetcode 322. 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例 1:

输入: coins = [1, 2, 5], amount = 11
输出: 3 
解释: 11 = 5 + 5 + 1

示例 2:

输入: coins = [2], amount = 3
输出: -1

说明:
你可以认为每种硬币的数量是无限的。

  • dp solution o(n^2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
dp = [0]
for money in range(1,amount+1):
dp.append(float('inf'))
for coin in coins:
if money-coin >= 0:
dp[-1] = min(dp[-1],dp[money - coin]+1)
if dp[-1] == float('inf'):return -1
return dp[-1]
  • dfs solution o(n*amount/coins[i])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
if amount == 0: return 0
coins.sort(reverse=True)
self.best = float('inf')
def dfs(start, coins, amount, cur):
if start == len(coins)-1:
if amount%coins[start] == 0:
self.best = min(self.best, cur + amount/coins[start])
else:
for i in range(amount/coins[start], -1, -1):
if cur + i >= self.best: break
dfs(start+1, coins, amount-i*coins[start], cur+i)
dfs(0, coins, amount, 0)
return self.best if self.best != float('inf') else -1