leetcode 322. Coin Change 贪心+动态规划

题目描述:

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

Example 1:

Input: coins = [1, 2, 5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1

Example 2:

Input: coins = [2], amount = 3
Output: -1

思路:(实质是一个完全背包问题)

思路同:https://blog.csdn.net/orangefly0214/article/details/91352014找零的另一个版本

根据上图,问题可以转化为递归或者迭代去求解。

问题等价于一个完全背包问题,完全背包问题的求解方法如下:

我们用j表示需要找零的总money,则dp[j]就等于

使用第i中硬币后剩下的money需要找零的求解数+1(“1”表示使用第i中硬币这一种解法)   和

不使用第i中硬币时的money需要找零的求解数,两者之间的较小的那个值。

详细可参加这个视频,讲的太好了

https://www.youtube.com/watch?v=jgiZlGzXMBw

实现:

使用dp将递归这种top-down的复杂运算转化为bottom-up来简化运算。这样在求解一个大问题的时候,它的子问题的最优解我们已经存储在了dp数组中,避免了重复计算。

import java.util.Arrays;
//leetcode 322
public class coinChangeDemo {
	//问题是一个完全背包问题
	public int coinChange(int[] coins, int amount) {
		int[] dp=new int[amount+1];
		Arrays.fill(dp, Integer.MAX_VALUE);
		dp[0]=0;
		for (int i = 0; i < coins.length; i++) {
			for (int j =coins[i]; j <=amount; j++) {//j表示需要找零的零钱数
//				j-coins[i];使用了第i种硬币,剩余需要找零的数目变为j-coins[i]
				if(dp[j-coins[i]]!=Integer.MAX_VALUE){
					dp[j]=Math.min(dp[j], dp[j-coins[i]]+1);
				}
			}	
		}
		if(dp[amount]==Integer.MAX_VALUE){
			return -1;
		}		
		return dp[amount];	        
	    }

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		coinChangeDemo cd=new coinChangeDemo();
		int[] coins={2};
		System.out.println(cd.coinChange(coins, 3));

	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值