1、爬楼梯
题目链接
题目要求
思路分析
题目要求求出到n级台阶的不同方法的个数,且每次可以爬1级或2级,那么我们可以知道爬到n级台阶可以有两种不同的情况,即
- 从n-1级爬到n级
- 从n-2级爬到n级
那么可以得出dp(n) = dp(n-1) + dp(n-2)
显然,爬到0(假设存在),1,2三级台阶是初始情况,接下来对初始化情况进行分析
- 爬到0级台阶相当于没爬记0
- 爬到1级台阶仅仅有一种情况记1
- 爬到2级台阶有两种情况记2
下面给出代码
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n+1];
if(n == 1){
return 1;
}
if(n == 2){
return 2;
}
if(n > 2){
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
}
return dp[n];
}
}
2、零钱兑换
题目链接
题目简介
思路分析
根据题目分析,达到amount元的方法有amount - coins[0…len-1] + 1种,例如示例1:
达到11元的方法有三种
- 10元加一元钱
- 9元加两元钱
- 6元加五元钱
那么凑成11元的最少钱币组合数就是:
min(到达10元的组合数,到达9元的组合数,到达6元的组合数) + 1
得到dp表达式
dp[i] = Math.min(dp[i],dp[i-coins[j]]+1);
初始数值就是0元钱(假设存在),没有任何组合方式即
dp[0] = 0;
下面给出代码
class Solution {
public int coinChange(int[] coins, int amount) {
//若为0元,则无法组成,直接返回
if(amount < 1){
return 0;
}
//定义dp数组,因为是从0开始,所以要有amount+1的长度
int[] dp = new int[amount + 1];
//填充超过当前大小的初始值,用于表示不可能,确定不成立情况以及比较大小
Arrays.fill(dp,amount+1);
//初始化dp
dp[0] = 0;
//dp[i]代表i元钱的组合方式
//有关系式dp[i] = dp[i-coins[0...coins.length-1]] + 1
//即i块钱可以由(i - 给出的面额之一) + 1
//这里的+1是因为存在了给出面额之一的钱数情况则再加一张这个面额的纸币即可
//为了求最小组合dp[i] = Math.min(dp[i],dp[i-coins[j]]+1);
for(int i = 0;i <= amount;i++){
for(int j = 0;j < coins.length;j++){
if(i >= coins[j]){
dp[i] = Math.min(dp[i],dp[i-coins[j]]+1);
}
}
}
//如果无法涉及到这种情况,则dp[amount]应该为初始值amount+1
if(dp[amount] == amount + 1){
return -1;
}
//返回结果
return dp[amount];
}
}