leetcode——动态规划——322. 零钱兑换

本文详细解析了零钱兑换问题的动态规划算法实现,通过计算凑成特定总金额所需的最少硬币数量,提供了完整的Java代码示例,并展示了如何初始化状态数组、迭代计算以及最终返回结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

dp[i]表示 金额 i 的硬币组合的硬币最小数量,dp[i]=min(dp[i-coin[j]+1),coin[j]表示不同硬币面额

322. 零钱兑换

难度中等1191

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1

你可以认为每种硬币的数量是无限的。

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp=new int[amount+1];
        dp[0]=0;
        Arrays.sort(coins);
        for(int i=1;i<=amount;i++){
            int j=0;
            dp[i]=amount+1; //将当前 i 的硬币组合 dp[i]设为超大值,如果不存在小于 i 的硬币,则dp[i]不会更新,即保持该边界外值(便于 return 时返回-1);另外,后续循环对更大的 i,进行处理时,如果需要用到的之前的 dp 不存在硬币组合,刚好这里的 dp 表示为超大值,一定不会作为 min 值对 dp 进行更新
            while(j<coins.length&&coins[j]<=i){
                dp[i]=Math.min(dp[i],1+dp[i-coins[j]]);
                j++;
            }
        }
        return dp[amount]==amount+1?-1:dp[amount];
    }
}

// class Solution {
//     public int coinChange(int[] coins, int amount) {
//         if(amount==0)   return 0;
//         int[] dp=new int[amount+1];   //dp[amount]表示 amount 需要的硬币数量
//         //可以先给 dp 赋值为amount+1,省去下面的嗯{dp[i-coin]!=0}、{(dp[i]==0}的判断
//         for(int coin:coins){
//             if(coin<=amount) dp[coin]=1;
//         }
//         for(int i=2;i<=amount;i++){
//             for(int coin:coins){
//                 if(coin<i&&dp[i-coin]!=0){
//                     if(dp[i]==0){
//                         dp[i]=dp[i-coin]+1;
//                     }else dp[i]=Math.min(dp[i],dp[i-coin]+1);
//                 }    
//             }
//             /*
//             if(dp[i]!=1){
//                 for(int j=i-1;j>i/2-1;j--){  //不需要这样子拼接,只需要拼上各个钞票面额然后进行比较即可
//                     if(dp[j]!=0&&dp[i-j]!=0){
//                         if(dp[i]==0){
//                             dp[i]=dp[j]+dp[i-j];
//                         }else dp[i]=Math.min(dp[i],dp[j]+dp[i-j]);
//                     }    
//                 }
//             }
//             */
//         }
//         return dp[amount]==0?-1:dp[amount];
//     }

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

//     */
// }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值