leetcode509:斐波那契数&&leetcode322:零钱兑换(动态规划)

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];
​
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值