一.509.斐波那契数列
解题思路
第一种:(自顶向下)
直接使用原函数递归
会有重复计算的问题
第二种:(自顶向下)
在原有的第一种解法的基础上进行优化,即进行了备忘录操作避免了重复计算的问题
第三种:(自底向上)
使用dp数组
代码
class Solution {
public int fib(int n) {
if(n==0 || n==1){
return n;
}
return fib(n-1)+fib(n-2);
}
}
class Solution {
public int fib(int n) {
int[] note = new int[n+1];
if(n<=0){
return 0;
}
return searchFib(note,n);
}
public int searchFib(int[] note,int n){
if (n==1 || n==2) return 1;
if (note[n]!=0){
return note[n];
}
note[n]=searchFib(note,n-1)+searchFib(note, n-2);
return note[n];
}
}
class Solution {
public int fib(int n) {
int[] nums = new int[2];
nums[0]=0;
nums[1]=1;
if (n<=1){
return nums[n];
}
for (int i=2;i<n;i++){
int sum = nums[0]+nums[1];
nums[0]=nums[1];
nums[1]=sum;
}
return nums[0]+nums[1];
}
}
二.322.零钱兑换问题
解题思路
第一种:
递归,有重复计算问题,会超时
第二种:
在第一种的基础上进行优化,使用笔记本剪枝,但是效率还是不高
第三种:dp动态规划
代码
class Solution {
public int coinChange1(int[] coins, int amount) {
if (amount<0) return -1;//递归的终止条件,说明兑换的方式不能够换出amount
if (amount==0) return 0;
int ans = Integer.MAX_VALUE,length=coins.length;
for (int i=0;i<length;i++){
int semple = coinChange1(coins,amount-coins[i]);
if (semple==-1) continue;
ans = Math.min(ans,semple+1);
}
return ans==Integer.MAX_VALUE?-1:ans;
}
}
class Solution {
int[] note;
public int coinChange(int[] coins, int amount) {
note = new int[amount+1];
Arrays.fill(note,-999);
return search(coins,amount);
}
public int search(int[] coins,int amount){
if (amount<0) return -1;//递归的终止条件,说明兑换的方式不能够换出amount
if (amount==0) return 0;
if (note[amount]!=-999) return note[amount];
int length = coins.length,res=Integer.MAX_VALUE;
for (int i=0;i<length;i++){
int semple = search(coins,amount-coins[i]);
if (semple==-1) continue;
res=Math.min(res,semple+1);
}
note[amount]=res==Integer.MAX_VALUE?-1:res;
return note[amount];
}
}
class Solution {
public int coinChange(int[] coins, int amount) {
/*
dp数组的具体含义就是
dp[2]=1
说明凑齐两元在最好的情况下只需要一枚2元的硬币
*/
//初始化dp数组
int[] dp = new int[amount+1];
Arrays.fill(dp,amount+1);
//base case
dp[0]=0;
if (amount==0) return 0;
if (amount<0) return -1;
for (int i=0;i<amount+1;i++){
for (int coin:coins){
if (i-coin<0) continue;
dp[i]=Math.min(dp[i],1+dp[i-coin]);
}
}
return dp[amount]==amount+1?-1:dp[amount];
}
}