golang 凑零钱算法

问题

给你 k 种面值的硬币,面值分别为 c1, c2 ... ck ,
每种硬币的数量无限,再给一个总金额 amount ,
问你最少需要几枚硬币凑出这个 金额,如果不可能凑出,算法返回 -1

思路

要凑出金额 11,至少要 dp(coins,11) 个硬币;
假如第一次凑1块,那么还有11-1块需要凑,要凑出金额 11-1,至少要 dp(coins,11-1) 个硬币;
假如第二次还是凑1块,那么还有10-1块需要凑,要凑出金额 10-1,至少要 dp(coins,10-1) 个硬币;
……
……
直到amount==0,刚好凑齐,否则无效

代码实现

package main

import (
	"fmt"
	"math"
)

func main() {
	var coins = []int{1, 2, 5}
	num := coinChange(coins, 11)
	fmt.Println(num)
}

// 凑零钱问题
func coinChange(coins []int, amount int) int {
	if amount == 0 {
		return 0
	}
	return helper(coins, amount)
}

func helper(coins []int, amount int) int {
	if amount == 0 {
		return 0
	}
	if amount < 0 {
		return -1
	}
	res := math.MaxInt32
	for _, coin := range coins {
		tmp := helper(coins, amount-coin)
		if tmp == -1 {
			continue
		}
		res = min(res, tmp+1)
	}
	if res == math.MaxInt32 {
		return -1
	}
	return res
}

func min(a, b int) int {
	if a <= b {
		return a
	}
	return b
}

  • 当然,其中还存在可以继续优化的地方,我们可以利用备忘录map记录已经计算过的,再次需要计算,直接从map中获取即可
posted @ 2020-12-06 21:36  A毛毛  阅读(403)  评论(0编辑  收藏  举报