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  }