JavaScript 每日一题---LeetCode 123. 买卖股票的最佳时机 III

题目描述:

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

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

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

解题思路:

        股票 I 是单次买卖,股票 II 是多次买卖,而股票 III 是两次买卖。单次买卖和多次买卖都只对应着两种状态,持有 / 未持有。而两次买卖则对应了五种状态,未买卖 / 第一次买入 / 第一次售出 / 第二次买入 / 第二次售出。这道题的关键仍然是现金流,初始资金为 0.其中,未买卖的状态是不用考虑的,现金流一直为 0.

         题目没有做出相关限制,所以理论上是可以当天多次买卖的,极限情况即可以一天就进行两次买卖,所以初始化状态就可以推出第一天的状态:第一次买入 = 第二次买入 = 第一天的售价,第一次卖出 = 第二次卖出 = 0.

         开始遍历数组,只需要用四个变量分别存储四个状态的局部最优解,同样符合 dp 的基本策略:一个最优决策序列的任何子序列本身一定是相对于子序列的初始和结束状态的最优决策序列。既然已进行了初始化,那么每次遍历时,某个状态没改变时仍保存上一天的状态,例如:

purchase1 = max( purchase1 , -prices[i])

        在运算之前 purchase1 仍保持前一天的状态,同样选择前一天与当天购入价较小的一个(这里是负数所以选 max,因为要求的是现金流,购入就等于现金流减少,所以为负数)。其他几种状态同理:

sell1 = max(sell1,prices[i] + purchase1)

purchase2 = max( purchase2 , sell1 - prices[i])

sell2 = max(sell2,prices[i]+purchase2)

完整代码:最后返回的是第二次售卖的状态,因为售出肯定比买入现金流多,而第二次售卖又包含了第一次售卖的情况(可能同一天两次买卖)

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
    const len=prices.length;
    if(len==0){
        return 0;
    }
    let pur1=-prices[0],pur2=-prices[0],sell1=0,sell2=0;
    for(var i=1;i

dp 是真折磨!

欢迎指正!

你可能感兴趣的:(LeetCode,for,JavaScript,javascript,leetcode,数据结构)