github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/leetcode/coin_change_test.go (about) 1 package leetcode 2 3 import ( 4 "strconv" 5 "testing" 6 ) 7 8 // 硬币问题 leetcode 322 9 // https://leetcode-cn.com/problems/coin-change/ 10 //coins 硬币, amount 期望的金额, 返回最少需要的硬币数量,如果不可解返回-1 11 func CoinCharge(coins []int, amount int) int { 12 dp := make([]int, amount+1) //dp存储的是 0~amount金额最小值的信息 13 dp[0] = 0 14 15 for i := 1; i <= amount; i++ { 16 dp[i] = amount + 1 17 for _, coin := range coins { 18 if coin <= i && dp[i-coin] != -1 && dp[i-coin]+1 < dp[i] { 19 dp[i] = dp[i-coin] + 1 20 } 21 } 22 if dp[i] > amount { 23 dp[i] = -1 24 } 25 } 26 27 return dp[amount] 28 } 29 30 func TestCoinChange(t *testing.T) { 31 type args struct { 32 coins []int 33 amount int 34 } 35 tests := []struct { 36 name string 37 args args 38 want int 39 }{ 40 {"[2] => 3", args{[]int{2}, 3}, -1}, 41 {"[2] => 4", args{[]int{2}, 4}, 2}, 42 {"[1,2,5] => 11", args{[]int{1, 2, 5}, 11}, 3}, 43 {"[1,3,5] => 11", args{[]int{1, 3, 5}, 11}, 3}, 44 } 45 for _, tt := range tests { 46 t.Run(tt.name, func(t *testing.T) { 47 if got := CoinCharge2(tt.args.coins, tt.args.amount); got != tt.want { 48 t.Errorf("CoinCharge() = %v, want %v", got, tt.want) 49 } 50 }) 51 } 52 } 53 54 // 递归回溯的写法 55 func CoinCharge2(coins []int, amount int) int { 56 ret := strconv.IntSize 57 f(0, 0, amount, coins, &ret) 58 if ret == strconv.IntSize { 59 return -1 60 } 61 return ret 62 } 63 64 // 65 func f(ca, cc, amount int, coin []int, ret *int) { 66 if ca >= amount { 67 if ca == amount { // 有解 68 if cc < *ret { 69 *ret = cc 70 } 71 } 72 return 73 } 74 for i := range coin { 75 if coin[i]+ca <= amount { 76 f(coin[i]+ca, cc+1, amount, coin, ret) 77 } 78 } 79 }