简单炒个股

206 阅读3分钟

买卖股票的最佳时机

一、问题描述

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

“买卖股票的最佳时机 II” 问题设定如下:给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。与只能进行一次买卖的 “买卖股票的最佳时机” 不同,在本题中,我们可以尽可能地完成更多的交易(多次买卖一支股票),但必须遵循一个规则:在再次购买前必须出售掉之前的股票 ,即不能同时参与多笔交易,目标是计算出能够获得的最大利润。

例如,给定价格数组 [7, 1, 5, 3, 6, 4],通过合适的买卖策略,我们可以实现最大利润。第一天价格为 7,第二天价格降到 1,此时买入,第三天价格升至 5 时卖出,获利 4;接着在第四天价格为 3 时再次买入,第五天价格涨到 6 时卖出,又获利 3。最终总利润为 7

二、思路1

当看读完题目后,第一个想法就是低买高卖,于是沿着这个思路我想到的是寻找股票波动的波峰与波谷,在波谷的时候买在波峰的时候买。这种方法需要考虑边界问题,判断波峰与波谷来决定是否买入或者卖出,同时还要记录是否持有股票。 代码如下:

var maxProfit = function(prices) {
    // 低买高卖:在波谷买入,波峰卖出(原始思路修复版)
    if (prices.length < 2) return 0;
    let profit = 0;
    let hasStock = false; // 跟踪是否持有股票
    let buyPrice = 0;

    for (let i = 0; i < prices.length; i++) {
        // 最后一天如果持有股票则卖出
        if (i === prices.length - 1) {
            if (hasStock) {
                profit += prices[i] - buyPrice;
                hasStock = false;
            }
            break;
        }

        // 波谷:当前价格低于后一天,且未持有股票时买入
        if (!hasStock && prices[i] < prices[i + 1]) {
            buyPrice = prices[i];
            hasStock = true;
        }
        // 波峰:当前价格高于后一天,且持有股票时卖出
        else if (hasStock && prices[i] > prices[i + 1]) {
            profit += prices[i] - buyPrice;
            hasStock = false;
        }
    }
    return profit;
};

三、思路2

更简单的做法是是贪心算法。贪心算法的本质是在每一步选择中都采取当前状态下的最优解,从而希望最终得到全局最优解。在股票买卖问题中,有一个关键规律:只要第二天的股价高于当天股价,就在当天买入,第二天卖出,这样就能保证每一次盈利都被纳入总利润中。

具体来说,我们遍历整个价格数组,从第二天开始,比较当天价格与前一天价格。如果当天价格大于前一天价格,说明存在盈利空间,将这个差值(即当天与前一天的价格差)累加到总利润中。通过这种方式,我们可以在满足交易规则的前提下,实现利润最大化。 代码如下:

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function (prices) {
  // 上涨就卖 下降不买
  let result = 0;
  
  for (let i = 1; i < prices.length; i++) {
    if (prices[i] > prices[i - 1]) result += prices[i] - prices[i - 1];
  }
  return result
};


在上述代码中,首先初始化利润 result0。然后通过 for 循环遍历价格数组,索引从 1 开始(因为要与前一天价格比较)。当发现当天价格高于前一天价格时,将价格差累加到 result 中。最后返回计算得到的最大利润。