122. 买卖股票的最佳时机 II [中等]

121 阅读2分钟

题目

给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。

在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。 返回 你能获得的 最大 利润 。

  • 来源:力扣(LeetCode)
  • 链接:leetcode-cn.com/problems/be…
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一

思路

  • 只要卖出的价钱比买入的价钱高就可以获利。
  • 如果买入的第二天又跌了,按照更低的价钱买入(持续有低价,持续按照低价买入)。
  • 如果上次卖便宜了,那么可以重新卖个高价(持续有高价,则持续重新卖;如果突然掉价了,那么就要重新买入了)。

代码

public int maxProfit(int[] prices) {
    int minPrice = Integer.MAX_VALUE;
    int maxProfit = 0;
    // 记录上一次卖出的价钱。如果为-1,表示还没有卖出过
    int lastPrice = -1;
    for (int i = 0; i < prices.length; i++) {
        if (prices[i] < minPrice) {
            // 表示买入
            minPrice = prices[i];
            lastPrice = -1;
        } else {
            if (prices[i] > lastPrice) {
                // 表示卖出
                maxProfit = maxProfit - (lastPrice == -1 ? 0 : (lastPrice - minPrice)) + (prices[i] - minPrice);
                lastPrice = prices[i];
            } else {
                // 表示买入
                minPrice = prices[i];
                lastPrice = -1;
            }
        }
    }
    return maxProfit;
}

复杂度

时间复杂度:O(n) 空间复杂度:O(1)

解法二

思路

动态规划的方法。

代码

public int maxProfit(int[] prices) {
    int n = prices.length;
    // dp[i][0] // 不持有第i天股票时的最大利润
    // dp[i][1] // 持有第i天股票时的最大利润
    int[][] dp = new int[n][2];
    dp[0][0] = 0; dp[0][1] = -prices[0];
    for (int i = 1; i < n; i++) {
        // 第i天不持有股票可以由2个状态迁移而来
        //    - 第i-1天也不持有股票
        //    - 第i-1天持有股票,而i天不持有股票,说明i天卖出了,可以获得利润
        dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
        dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
    }
    return dp[n-1][0];
}

复杂度

时间复杂度:O(n) 空间复杂度:O(n)

update20220804

class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        int buy = -prices[0];
        int sell = 0;
        for (int i = 1; i < n; i++) {
            buy = Math.max(buy, sell - prices[i]);
            sell = Math.max(sell, buy + prices[i]);
        }
        return sell;
    }
}

解法三

思路

贪心算法

其实只要后一天比前一天的价钱高,就能获利。

注意:可以这么做是因为,可以在同一天买入也可以在同一天卖出。

代码

public int maxProfit(int[] prices) {
    int res = 0;
    for (int i = 1; i < prices.length; i++) {
        res += Math.max(0, prices[i] - prices[i-1]);
    }
    return res;
}

复杂度

时间复杂度:O(n) 空间复杂度:O(1)

参考

-买卖股票,动态规划