day45爬楼梯进阶_零钱兑换_完全平方数

文章介绍了使用动态规划方法解决力扣上的三道问题:70.爬楼梯,322.零钱兑换和279.完全平方数。通过初始化状态数组,遍历并更新状态来找到最优解,涉及组合计数和最小件数计算。
摘要由CSDN通过智能技术生成

力扣70.爬楼梯

题目链接:https://leetcode.cn/problems/climbing-stairs/
##思路
本题和组合总和4相像,先迈一个台阶再迈两个台阶,和先迈两个台阶再迈一个台阶是不一样的,所以这里求的是组合数。

完整代码

class Solution {
    public int climbStairs(int n) {
        if(n < 2) return n;
        int[] dp = new int[n+1];
        int[] step = {1,2};
        dp[0] = 1;
        for (int j = 0; j <= n; j++) {
            for (int i = 0;i < step.length;i++) {
                if(j >= step[i]) {
                    dp[j] += dp[j - step[i]];
                }
            }
        }
        return dp[n];
    }
}

力扣322.零钱兑换

题目链接:https://leetcode.cn/problems/coin-change/

完整思路

1.dp[j]含义:装满背包容量j的最小物品件数为dp[j]

2.递推公式:

(1)要将物品i装入背包中,那么背包得先预留出i的空间,即j-coins[i],这种空间下,背包内的最小物品件数为dp[j-coins[i]],再加上物品i也就是一件,是dp[j - coins[i]] + 1

(2)与原先的dp[j]对比,取较小值

3.初始化:amount为0时,最小件数是0,所以dp[0]=0。并且在递推公式中,取的是较小值,为了dp[j]不被覆盖,初始值都为Integer.MAX_VALUE

4.遍历顺序:本题不论是(1)先物品再背包,求的是组合数;(2)先背包再物品,求的是排列数。都可以,因为求 的是最小件数,都没影响。

5.打印数组

完整代码

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount+1];
        for (int i = 0; i < dp.length; i++) {
            dp[i] = Integer.MAX_VALUE;
        }
        dp[0] = 0;
        for (int i = 0; i < coins.length; i++) {
            for (int j = coins[i]; j <= amount; j++) {
				//如果等于最大值,说明dp[j-coins[i]]没被更新过,所以不可达,不用更新
                if(dp[j-coins[i]] != Integer.MAX_VALUE) {
                    dp[j] = Math.min(dp[j - coins[i]] + 1, dp[j]);
                }
            }
        }
        if(dp[amount] == Integer.MAX_VALUE){
            return -1;
        }else{
            return dp[amount];
        }
    }
}

力扣279.完全平方数

题目链接:https://leetcode.cn/problems/perfect-squares/

思路

和零钱兑换一样

完整代码

class Solution {
    public int numSquares(int n) {
        int[] dp =new int[n+1];
        for (int i = 0; i < dp.length; i++) {
            dp[i] = Integer.MAX_VALUE;
        }
        dp[0] = 0;
        for (int i = 1; i*i <= n; i++) {
            for (int j = i*i; j <= n; j++) {
                dp[j] = Math.min(dp[j-i*i]+1,dp[j]);
            }
        }
        return dp[n];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值