代码随想录算法训练营day49||121. 买卖股票的最佳时机||122.买卖股票的最佳时机II

121. 买卖股票的最佳时机

题目描述:

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

这题暴力的解法和贪心解法都比较容易想到,我就不写了,主讲动态规划

动规五部曲:

1.dp数组及其下标的含义:

dp[i][0]:到第i天时持有股票的最大收益为dp[i][0].

dp[i][1]:到第i天时不持有股票的最大收益为dp[i][1].

介绍一个持有股票和买入股票的区别,持有股票是在第i天之前包括第i天就已经买入了股票,买入股票代表第i天买入了股票。

不持有股票和卖出股票同理:不持有股票表示第i天之前就已经卖出了股票,卖出股票表示第i天当前卖出的股票

2.递推公式:

dp[i][0]=max(dp[i-1][0],-price[i])。为什么呢?这是在确定买入股票时的天数,如果是在第i-1天之前买入股票,那么dp[i][0]=dp[i-1][0].如果是第i天买入股票,dp[i]=-price[i].

dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]).为什么?这是确定卖出股票的天数,如果股票是在第i-1天之前卖出股票的收益最大,那么dp[i][1]=dp[i-1][1].如果股票是在第i天卖出的收益最大,那么dp[i][1]=dp[i-1][0]+prices[i].

3.初始化

dp[0][0]=-prices[0], dp[1][0]=0;

4.遍历顺序从递推公式上看是从前往后遍历

5.验证dp

class Solution {
public:
    int maxProfit(vector& prices) {
        int len = prices.size();
        if (len == 0) return 0;
        vector> dp(len, vector(2));
        dp[0][0] -= prices[0];
        dp[0][1] = 0;
        for (int i = 1; i < len; i++) {
            dp[i][0] = max(dp[i - 1][0], -prices[i]);
            dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
        }
        return dp[len - 1][1];
    }
};

122.买卖股票的最佳时机II

题目描述:

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

思路:

本题与上一题的不同之处在于本题可以不断进行买入卖出重复操作。所以在持有股票的情况会有所不用,如果是第i-1天之前就持有股票,那么dp[i][0]=dp[i-1][0],但是如果是第i天买入股票,第i天之前可能就进行了买入卖出赚取了利润,所以我们还要加上之前的利润,dp[i][0]=dp[i-1][1]-prices[i].

class Solution {
public:
    int maxProfit(vector& prices) {
        //动规五部曲:1.dp[i][0],dp[i][1]数组及其下标的定义:
        //dp[i][0]:到第i天时持有股票的最大收益为dp[i][0].
        //dp[i][1]:到第i天不持有股票的最大收益为dp[i][1].
        //递推公式:dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i])
        //dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]);
        //初始化:dp[0][0]=-prices[0]   dp[0][1]=0;
        //遍历顺序:前往后遍历
        int len=prices.size();
        vector> dp(len,vector(2));
        dp[0][0]=-prices[0]; dp[0][1]=0;
        for(int i=1;i

你可能感兴趣的:(算法,动态规划,leetcode)