【算法|动态规划】Leetcode 123.买卖股票的最佳时机Ⅲ
本文最后更新于 426 天前,其中的信息可能已经有所发展或是发生改变。
35.买卖股票的最佳时机Ⅲ

123.买卖股票的最佳时机Ⅲ


题目描述

  • 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
  • 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例1:

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

示例2:

输入: nums = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票

示例3:

输入: nums = [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0。

提示:

  • 1 <= prices.length <= 3 * 10^5
  • 0 <= prices[i] <= 10^5

解题思路

i天对股票有以下几种状态:①未持有;②第一次持有;③第一次不持有;④第二次持有;⑤第二次不持有

  1. 确定dp数组以及下标的含义
    dp[i][0] 表示第i天未持有股票所得的最多现金
    dp[i][1] 表示第i天第一次持有股票所得的最多现金=延续前一天第一次持有状态+今天第一次买入未持有
    dp[i][2] 表示第i天第一次不持有股票所得的最多现金=延续前一天第一次不持有状态+今天卖出前一天第一次持有
    dp[i][3] 表示第i天第二次持有股票所得的最多现金=延续前一天第二次持有的状态+今天买入第一次持有的股票
    dp[i][4] 表示第i天第二次不持有股票所得的最多现金=延续前一天第二次不持有状态+今天卖出第二次持有股票
  2. 递推公式
  • dp[i][0] = dp[i-1][0]
  • dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
  • dp[i][2] = max(dp[i-1][2], dp[i-1][1] + prices[i])
  • dp[i][3] = max(dp[i-1][3], dp[i-1][2] - prices[i])
  • dp[i][4] = max(dp[i-1][4], dp[i-1][3] + prices[i]
  1. dp数组初始化
  • dp[0][0] = 0
  • dp[0][1] = -prices[0]
  • dp[0][2] = 0
  • dp[0][3] = -prices[0]
  • dp[0][4] = 0
  1. 确定遍历顺序
  2. 根据递推公式可以看出,dp[i] 都是由 dp[i-1] 推出来的,那么遍历顺序一定是从前往后遍历。
  3. 打印dp数组

代码实现

  • 核心模式
class Solution{
public:
    int maxProfit(vector<int>& prices){
        int len = prices.size();
        if (len == 0) return 0;
        vector<vector<int>> dp(len, vector<int>(5, 0));

        // initialize the DP array
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        dp[0][2] = 0;
        dp[0][3] = -prices[0];
        dp[0][4] = 0;

        for (int i = 1; i < len; i++){
            dp[i][0] = dp[i - 1][0];
            dp[i][1] = std::max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
            dp[i][2] = std::max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
            dp[i][3] = std::max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
            dp[i][4] = std::max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
        }

        return dp[len - 1][4];
    }
};
#include <iostream>
#include "dynamicPro.h"

class Solution{
public:
    int maxProfit(vector<int>& prices){
        int len = prices.size();
        if (len == 0) return 0;
        vector<vector<int>> dp(len, vector<int>(5, 0));

        // initialize the DP array
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        dp[0][2] = 0;
        dp[0][3] = -prices[0];
        dp[0][4] = 0;

        for (int i = 1; i < len; i++){
            dp[i][0] = dp[i - 1][0];
            dp[i][1] = std::max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
            dp[i][2] = std::max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
            dp[i][3] = std::max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
            dp[i][4] = std::max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
        }

        print2DVector(dp);

        return dp[len - 1][4];
    }
};

int main(){
    vector<int> case1 = {3, 3, 5, 0, 0, 3, 1, 4};
    vector<int> case2 = {1, 2, 3, 4, 5};
    vector<int> case3 = {7, 6, 4, 3, 1};

    Solution solution;
    cout << "DP Array = " << solution.maxProfit(case1) << endl;
    cout << "DP Array = " << solution.maxProfit(case2) << endl; 
    cout << "DP Array = " << solution.maxProfit(case3) << endl; 

    return 0;
}
  • 输出
DP Array = [[0, -3, 0, -3, 0], [0, -3, 0, -3, 0], [0, -3, 2, -3, 2], [0, 0, 2, 2, 2], [0, 0, 2, 2, 2], [0, 0, 3, 2, 5], [0, 0, 3, 2, 5], [0, 0, 4, 2, 6]]
6
DP Array = [[0, -1, 0, -1, 0], [0, -1, 1, -1, 1], [0, -1, 2, -1, 2], [0, -1, 3, -1, 3], [0, -1, 4, -1, 4]]
4
DP Array = [[0, -7, 0, -7, 0], [0, -6, 0, -6, 0], [0, -4, 0, -4, 0], [0, -3, 0, -3, 0], [0, -1, 0, -1, 0]]
0
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇