IT程序员客栈

菜鸟系列 Golang 实战 Leetcode —— 322. 零钱兑换

有兴趣的关注IT程序员客栈哦

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

示例 1:

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

输入: coins = [2], amount = 3
输出: -1
说明:
你可以认为每种硬币的数量是无限的。

题解 1:

可以采用动态规划,自底向上求值

func coinChange(coins []int, amount int) int {
    // 动态规划算法求解
    var dp =make([]int,amount+1)
    for i:=0;i<amount+1;i++{
        dp[i]=amount+1
    }
    dp[0]=0
    for i:=1;i<=amount;i++{
        for j:=0;j<len(coins);j++{
            if coins[j]==i{
                dp[i]=1
            }else if i>coins[j]{
                if dp[i]>dp[i-coins[j]]+1{
                    dp[i]=dp[i-coins[j]]+1
                }
            }
        }
    }
    if dp[amount]>amount{
        return -1
    }else{
        return dp[amount]
    }
}

题解 2:

考虑通过贪心算法解决,要求钱币数量最少,则优先使用面额较大的钱币。

func coinChange(coins []int, amount int) int {
    // 贪心算法求解
    if amount==0{
        return 0
    }
    var res = amount+1
    sort.Slice(coins,func(i,j int)bool{
        if coins[i]>coins[j]{
            return true
        }
        return false
    })
    help(coins,amount,0,0,&res)
    if res>amount{
        return -1
    }
    return res
}

func help(coins []int, amount int, index int, count int, res *int){
    if amount==0{
        if *res>count{
            *res=count
        }
        return 
    }
    if index==len(coins){
        return
    }
    for k:=amount/coins[index];k>=0&&k+count< *res;k--{
        help(coins, amount-k*coins[index],index+1,count+k,res)
    }
}
posted @ 2020-03-08 14:56  IT程序员客栈  阅读(444)  评论(0编辑  收藏  举报
IT程序员客栈