123. Best Time to Buy and Sell Stock III***

网友投稿 596 2022-10-12

123. Best Time to Buy and Sell Stock III***

123. Best Time to Buy and Sell Stock III***

123. Best Time to Buy and Sell Stock III***

​​you have an array for which the ​​ith​​​ element is the price of a given stock on day ​​i​​.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).

Example 1:

Input: [3,3,5,0,0,3,1,4]Output: 6Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3. Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 =

Example 2:

Input: [1,2,3,4,5]Output: 4Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 =

Example 3:

Input: [7,6,4,3,1]Output: 0Explanation: In this case, no transaction is done, i.e. max profit =

解题思路

强烈推荐 ​​Most consistent ways of dealing with the series of stock problems​​, 文章实在精彩啊, 将有关 Stock 的题总结了一遍, 探索了这些题之间的一致性.

C++ 实现 1

需要注意到的是, 一个隐含的影响 max profit 的因素是我们手中所拥有的股票数量. 因为在每一天我们所能采取的行动只有三种: sell, buy 以及 rest. 然而, 要完成 ​​sell​​​ 这个过程, 必须手上拥有一份股票; 而要完成 ​​buy​​​ 这个过程, 则必须保证手上没有任何股票. 因此, 倘若设置 ​​T[i][k]​​​ 表示在进行最多 ​​k​​​ 次交易的情况下在第 ​​i​​​ 天所能获得最大收益, 那么它其实可以分成两个部分: ​​T[i][k][0]​​​ 以及 ​​T[i][k][1]​​​, 前者表示采取某种行动之后手上股票变成 0 份所在第 ​​i​​​ 天所能获得的最大收益, 而后者表示采取某种行动之后手上股票变成 1 份在第 ​​i​​ 天所能获得的最大收益. 递推关系能写成:

Base cases:T[-1][k][0] = 0, T[-1][k][1] = -InfinityT[i][0][0] = 0, T[i][0][1] = -InfinityRecurrence relations:T[i][k][0] = max(T[i-1][k][0], T[i-1][k][1] + prices[i]) # sellT[i][k][1] = max(T[i-1][k][1], T[i-1][k-1][0] - prices[i]) # buy

为了找到最大的收益, 我们只需要遍历 ​​prices​​​, 并不断更新 ​​T[i][k][0]​​​ 以及 ​​T[i][k][1]​​​, 而最后一天的最大收益就是 ​​T[i][k][0]​​, 手上是没有股票才能获得最大收益.

上面是通用的公式, 而题目中要求 ​​K = 2​​, 此时, 递推公式变为:

T[i][2][0] = max(T[i-1][2][0], T[i-1][2][1] + prices[i])T[i][2][1] = max(T[i-1][2][1], T[i-1][1][0] - prices[i])T[i][1][0] = max(T[i-1][1][0], T[i-1][1][1] + prices[i])T[i][1][1] = max(T[i-1][1][1], -prices[i])

实现代码如下:

class Solution {public: int maxProfit(vector& prices) { vector T1(prices.size() + 1); T1[0] = 0; int s0 = 0, s1 = INT32_MIN; for (int i = 0; i < prices.size(); ++ i) { s0 = std::max(s0, s1 + prices[i]); s1 = std::max(s1, -prices[i]); T1[i + 1] = s0; } s0 = 0, s1 = INT32_MIN; for (int i = 0; i < prices.size(); ++ i) { s0 = std::max(s0, s1 + prices[i]); s1 = std::max(s1, T1[i] - prices[i]); } return s0; }};

作者的实现更贴近公式:

public int maxProfit(int[] prices) { int T_i10 = 0, T_i11 = Integer.MIN_VALUE; int T_i20 = 0, T_i21 = Integer.MIN_VALUE; for (int price : prices) { T_i20 = Math.max(T_i20, T_i21 + price); T_i21 = Math.max(T_i21, T_i10 - price); T_i10 = Math.max(T_i10, T_i11 + price); T_i11 = Math.max(T_i11, -price); } return T_i20;}

C++ 实现 2

用数组 ​​T​​​ 来保存每个 ​​k - 1​​​ 的状态. 这个方便扩展到 K 为其他值的情况. 可能需要对 ​​T​​ 进行优化.

class Solution {public: int maxProfit(vector& prices) { int K = 2; // 实际上, 不论 K 为多大, T 设置为 (2, prices.size() + 1) 的大小就行了 // 但这里为了理解方便, 就设置为 (K + 1, prices.size() + 1) 便于推广到 K != 2 的情况. vector> T(K + 1, vector(prices.size() + 1, 0)); int s0 = 0, s1 = INT32_MIN; for (int k = 0; k < K; ++ k) { s0 = 0, s1 = INT32_MIN; for (int i = 0; i < prices.size(); ++ i) { s0 = std::max(s0, s1 + prices[i]); // sell s1 = std::max(s1, T[k][i] - prices[i]); // buy T[k + 1][i + 1] = s0; } } return s0; }};

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot整合Lombok及常见问题解决
下一篇:Panels 是一个可以轻松地将滑动呼出面板添加到应用程序的框架(panel是什么会议形式)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~