力扣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];
}
}