leetcode509:斐波那契数
-
题目:斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1 给定 n ,请计算 F(n) 。
-
思路:斐波那契数是动态规划题目,需要解决重叠子问题
-
重叠子问题:采用备忘录进行解决,即生成一个数组,记录重叠的数据 (int dp = new int[n+1])
-
因为斐波那契数只需记录备忘录中的前两项的值,故可对其进行进一步优化
class Solution {
public int fib(int n) {
if(n==0||n==1){
return n;
}
//建立备忘录,解决动态规划的重叠子问题
int dp_i_1 = 1;
int dp_i_2 = 0;
for(int i =2;i<=n;i++){
//dp[n] = dp[n-1]+dp[n-2]
int dp_1 = dp_i_1+dp_i_2;
dp_i_2 = dp_i_1;
dp_i_1 = dp_1;
}
return dp_i_1;
}
}
leetcode322:零钱兑换
-
题目:给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。你可以认为每种硬币的数量是无限的。
-
思路:解题代码有解题思路。
-
此题为一道动态规划问题,解决重复子问题和最优子结构问题。
class Solution {
//准备备忘录数组
int[] dp;
public int coinChange(int[] coins, int amount) {
//声明并实例化备忘录数组且均赋值为-666,-666为不可能取到的金额
dp = new int[amount+1];
Arrays.fill(dp,-666);
//递归函数 dp
return dp(coins,amount);
}
public int dp(int[] coins,int amount){
//如果需要的钱数为0,则返回0
if(amount==0) return 0;
//如果需要的钱数小于,则返回-1
if(amount<0) return -1;
//当备忘录数组之前取过该金额的值,则直接返回原数组下标值
if(dp[amount]!=-666){
return dp[amount];
}
//定义结果为最大值
int res = Integer.MAX_VALUE;
//遍历 硬币数组
for(int coin: coins){
//数组coins从大到小开始遍历,amound - coin(硬币最大值)仍然大于等于0,则说明 结果+1;
int subProblem = dp(coins,amount-coin);
//否则,amound - coin(硬币最大值)仍然小于0,则继续遍历下个值,一直循环,直至出现结果
if(subProblem==-1) continue;
res = Math.min(res,subProblem+1);
}
dp[amount] =(res==Integer.MAX_VALUE?-1:res) ;
return dp[amount];
}
}
1353

被折叠的 条评论
为什么被折叠?



