前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 322. Coin Change Python 动态规划/BFS解法

LeetCode 322. Coin Change Python 动态规划/BFS解法

作者头像
大鹅
发布2021-06-15 15:30:23
4810
发布2021-06-15 15:30:23
举报

题目描述

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.You may assume that you have an infinite number of each kind of coin.

Example 1: coins = [1, 2, 5], amount = 11 return 3 (11 = 5 + 5 + 1) Example 2: coins = [2], amount = 3 return -1.

Brute Force暴力求法(超时)

代码语言:javascript
复制
class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        min_count = 9999
        coins.sort(reverse=True)
        length = len(coins)
        if length == 1 and amount % coins[0] != 0:
            return -1
        elif amount % coins[0] == 0:
            return int(amount / coins[0])
        count_list = [0] * length
        i = 0
        while amount >= 0:
            count_list[i] = int(amount / coins[i])
            amount -= count_list[i] * coins[i]
            i += 1
            print(i, amount, count_list)
            if amount == 0:
                temp_sum = sum(count_list)
                if temp_sum < min_count:
                    min_count = temp_sum
            if i >= length:
                j = i - 2
                while j > 0 and count_list[j] == 0:
                    j -= 1
                if j == 0 and count_list[j] <= 0:
                    break
                if j >= length - 1:
                    return -1
                else:
                    count_list[j] -= 1
                    amount += coins[j]
                    i = j + 1
                    for k in range(i, length):
                        if count_list[k] != 0:
                            amount += count_list[k] * coins[k]
                            count_list[k] = 0
        if min_count == 9999:
            return -1
        else:
            return min_count

DP动态规划#1(超时)

基本思路:用dp存储硬币数量,dp[i] 表示凑齐钱数 i 需要的最少硬币数,那么凑齐钱数 amount 最少硬币数为:固定钱数为 coins[j] 一枚硬币,另外的钱数为 amount - coins[j] 它的数量为dp[amount - coins[j]],j 从0遍历到coins.length - 1:

代码语言:javascript
复制
class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        dp = [0]
        length = len(coins)
        for i in range(1, amount + 1):
            dp += [9999]
            for j in range(length):
                if i >= coins[j] and dp[int(i - coins[j])] != 9999:
                    dp[i] = min(dp[i], dp[i - coins[j]] + 1)
        if dp[amount] == 9999:
            return -1
        return dp[amount]

DP动态规划#2(优化)

dp[x + c] = min(dp[x] + 1, dp[x + c])

代码语言:javascript
复制
class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        dp = [0] + [-1] * amount
        for x in range(amount):
            if dp[x] < 0:
                continue
            for c in coins:
                if x + c > amount:
                    continue
                if dp[x + c] < 0 or dp[x + c] > dp[x] + 1:
                    dp[x + c] = dp[x] + 1
        return dp[amount]

BFS广度优先搜索解法

将问题转化为求X轴0点到坐标点amount的最短距离(每次向前行进的合法距离为coin的面值)

代码语言:javascript
复制
class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        if amount == 0:
            return 0
        value1 = [0]
        value2 = []
        nc =  0
        visited = [False]*(amount+1)
        visited[0] = True
        while value1:
            nc += 1
            for v in value1:
                for coin in coins:
                    newval = v + coin
                    if newval == amount:
                        return nc
                    elif newval > amount:
                        continue
                    elif not visited[newval]:
                        visited[newval] = True
                        value2.append(newval)
            value1, value2 = value2, []
        return -1

参考文献

  1. http://bookshadow.com/weblog/2015/12/27/leetcode-coin-change/
  2. https://leetcode.com/problems/coin-change/discuss/77361
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-01-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
  • Brute Force暴力求法(超时)
  • DP动态规划#1(超时)
  • DP动态规划#2(优化)
  • BFS广度优先搜索解法
  • 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档