322. Coin Change

	int maxVal = 1000000000; // 把非法的值设置为我们期望方向的反方向
	public int search(int idx, int amount, int[] coins)
	{
		if (amount == 0)
			return 0;
		if (amount < 0)
			return maxVal; // 返会非常大的数,表示非法(不可以返回-1)
		if (idx >= coins.length)
			return maxVal; // 返会非常大的数,表示非法(不可以返回-1)
		// 两种决策,(只使用某一号硬币,使用其他)
		int a = search(idx, amount-coins[idx], coins) + 1;
		int b = search(idx+1, amount, coins);
		return Math.min(a,b);
	}
	
	 public int coinChange(int[] coins, int amount)
	 {
		 int res =  search(0, amount, coins);
		 if (res < maxVal)
		 {
			 return res;
		 }
		 else
		 {
			 return -1;
		 }
	 }

 记忆化搜索改进:(还是会超时,因为amount可能会很大)

	 static int[][] f = new int[1000][1000000];
	 int maxVal = 1000000000; // 把非法的值设置为我们期望方向的反方向
         int search(int idx, int amount, int[] coins)
   	 {
   		if (amount == 0)
   			return 0;
   		if (amount < 0)
   			return maxVal; // 返会非常大的数,表示非法(不可以返回-1)
   		if (idx >= coins.length)
   			return maxVal; // 返会非常大的数,表示非法(不可以返回-1)
   		// 两种决策,(只使用某一号硬币,使用其他)
   		int a = search(idx, amount-coins[idx], coins) + 1;
   		int b = search(idx+1, amount, coins);
   		f[idx][amount] =  Math.min(a,b);
   		return f[idx][amount];
   	}
   	
   	 public int coinChange(int[] coins, int amount)
   	 {
   		 // 初始化f数组
   		 for (int i=0; i<1000; i++)
   		 {
   			 for (int j=0; j<1000000; j++)
   			 {
   				 f[i][j] = -1;
   			 }
   		 }
   		 // 搜索
   		 int res =  search(0, amount, coins);
   		 if (res < maxVal)
   		 {
   			 return res;
   		 }
   		 else
   		 {
   			 return -1;
   		 }
   	 }

改为迭代实现(自底向上计算):

用dp存储硬币数量,dp[i] 表示凑齐钱数 i 需要的最少硬币数,那么凑齐钱数 amount 最少硬币数为:

固定钱数为 coins[j] 一枚硬币,另外的钱数为 amount - coins[j] 它的数量为dp[amount - coins[j]],j 从0遍历到

coins.length - 1:

    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount + 1];
        for (int i = 1; i <= amount; i++) {
            dp[i] = 0x7fffffff;
            for (int j = 0; j < coins.length; j++)
                if (i >= coins[j] && dp[i - coins[j]] != 0x7fffffff)  //①
                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
        }
        return dp[amount] == 0x7fffffff ? -1 : dp[amount];
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值