Leetcode 剑指系列 Day 8 动态规划

1.剑指 Offer 10- I. 斐波那契数列

初步思路:题知条件已经给出了递归公式,采用递归做这题无疑,于是写下了如下代码:

class Solution {
public:
    int fib(int n) {
        //边界条件
        if(n == 0) return 0;
        if(n == 1) return 1;
        //递归
        return (fib(n - 1) + fib(n - 2)) % 1000000007;
    }
};

喜提超时。

总结的原因是有这种方法有大量的重复计算,如 fib(n) 和 fib(n - 1) 均需要计算 fib(n - 2)。

在上一个方法的基础上,既然从 fib(n) 向下计算会发生大量重复计算,那么从 fib(0) 向 fib(n)计算即可解决这样的问题。 

修改代码如下:

class Solution {
public:   
    int fib(int n) {
        //边界条件
        if(n == 0) return 0;
        if(n == 1) return 1;
        int ans = 0, A = 0, B = 1;
        for(int i = 2; i <= n ; i++){
            ans = (A + B) % 1000000007;
            A = B;
            B = ans;
        }
        return ans;
    }
};

通过了且效率很高。

2.剑指 Offer 10- II. 青蛙跳台阶问题

注:关于讨论可能性的问题大都含有递归的性质

关于递归的问题,我们要考虑边界条件与递归法则

        边界条件:

即numWays(0) = 1, numWays(1) = 1;

        递归法则:

青蛙最后一次运动有两种可能性,跳一步或者两步,那么青蛙到达最后一步前所位置的可能性种数为numWays(n - 1)或者numWays(n - 2),分别对应最后跳一步或者两步。

那么很好理解numWays(n) = numWays(n - 1) + numWays(n - 2);

分析到此发现,这道题与斐波那契数列十分相似,只有numWays(0) = 1的改变。

得到如下代码:

class Solution {
public:
    int numWays(int n) {
        //边界条件
        if(n == 0) return 1;
        if(n == 1) return 1;
        int ans = 0, A = 1, B = 1;
        for(int i = 2; i <= n ; i++){
            ans = (A + B) % 1000000007;
            A = B;
            B = ans;
        }
        return ans;
    }
};

3.剑指 Offer 63. 股票的最大利润

 动态规划思考过程(from Krahets):

        状态定义:设 dp[i] 为以price[i] 结尾所能获取利润的最大值,即前 i 天的最大利润;

        转移方程:那么很好想到dp[i] 应该为 dp[i - 1] 与第 i 天卖出的最大值;即有 dp[i] = max( dp[i - 1], price[i] - min(price[0 : i]));

        初始状态:dp[0] = 0;

        返回值:dp[n - 1] 其中n为数组长度。

根据如上思路,可得到如下代码:其中minValue用于在遍历过程中记录前 i 项的最小值

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size() == 0 || prices.size() == 1)
            return 0;
        int ans = 0, temp = 0;
        int minValue = prices[0];
        for(int i = 1 ; i < prices.size(); i++){
            if(i == 1 || prices[i - 1] < minValue) 
                minValue = prices[i - 1];
            temp = prices[i] - minValue;
            ans = ans > temp ? ans : temp;
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值