LeetCode518、零钱兑换II(完全背包问题)

题目描述

https://leetcode-cn.com/problems/coin-change-2/
在这里插入图片描述

解法

完全背包问题,框架:

  • 确定状态,就是问题中的变量有哪些——1、不同种类的硬币;2、总金额数;3、所用硬币数目;然后根据题目,我们只需要使用前两个量就能描述出当前的问题,说明dp数组为二维,且两个维度分别对应1、2变量。
  • dp数组下定义:dp[i][j]表示前i种硬币能凑出金额为j的方法数,严格相信这个定义
  • 确定递推过程:如果第i个硬币装得下,我可以选择不装,则dp[i][j] = dp[i-1][j],选择装,则p[i][j] = dp[i][j-coins[i-1]],所以这种情况下dp[i][j] = dp[i-1][j]+dp[i][j-conis[i-1]];如果装不下,则dp[i][j] = d[i-1][j]
  • 如果无法递推成功,则返回第二步,dp数组定义错误,重新思考dp数组的定义
  • 思考边界情况:dp[i][0]就是金额为0的方法,只有一种,就是不凑,按照题目的结果为1,dp[0][j]=0,表示没有金币来凑

最后我们编写代码:

class Solution {
    
    
    public int change(int amount, int[] coins) {
    
    
        if(amount==0) return 1;
        if( coins==null || coins.length==0) return 0;
        int [][]dp = new int[coins.length+1][amount+1];//表示前i种硬币组合为j元的可能方法数
        //边界 dp[0][j]=0 dp[i][0]=1 
        for(int i=0;i<=coins.length;i++){
    
    
            dp[i][0] = 1;
        }
        //递推方程
        for(int i=1;i<=coins.length;i++){
    
    
            for(int j=1;j<=amount;j++){
    
    
                if(j-coins[i-1]>=0){
    
    //当前硬币装得下
                    dp[i][j] = dp[i-1][j] //不装
                                + dp[i][j-coins[i-1]];//装下该硬币,但是因为数量无限个,可以继续装
                }else//装不下
                    dp[i][j] = dp[i-1][j];
            }
        }
        return dp[coins.length][amount];


    }
}

在这里插入图片描述

然后从解法上看到dp[i][j]和之前的两个状态有关,可以利用状态压缩来降低空间复杂度:

  • 一维数组dp[j]
class Solution {
    
    
    public int change(int amount, int[] coins) {
    
    
        if(amount==0) return 1;
        if( coins==null || coins.length==0) return 0;
        int []dp = new int[amount+1];//表示前i种硬币组合为j元的可能方法数
        //边界 dp[0][j]=0 dp[i][0]=1 
        dp[0] = 1;
        //递推方程
        for(int i=1;i<=coins.length;i++){
    
    
            for(int j=1;j<=amount;j++){
    
    
                if(j-coins[i-1]>=0){
    
    //当前硬币装得下
                    dp[j] = dp[j] //不装
                                + dp[j-coins[i-1]];//装下该硬币,但是因为数量无限个,可以继续装
                }
                // }else//装不下
                //     dp[j] = dp[j];
            }
        }
        return dp[amount];


    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44861675/article/details/114577408
今日推荐