LeetCode-188. Best Time to Buy and Sell Stock IV [C++][Java]

LeetCode-188. Best Time to Buy and Sell Stock IVhttps://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/

题目描述

You are given an integer array prices where prices[i] is the price of a given stock on the ith day, and an integer k.

Find the maximum profit you can achieve. You may complete at most k transactions.

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

Example 1:

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

Example 2:

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

Constraints:

  • 0 <= k <= 100
  • 0 <= prices.length <= 1000
  • 0 <= prices[i] <= 1000

解题思路

  • buy[j] 的状态转移

    • buy[j] = max(buy[j], sell[j-1] - prices[i])

    • 在第 i 天,可以选择不操作(保持之前的 buy[j]),或者在第 j-1 笔交易的基础上买入股票(sell[j-1] - prices[i])。

  • sell[j] 的状态转移

    • sell[j] = max(sell[j], buy[j] + prices[i])

    • 在第 i 天,可以选择不操作(保持之前的 sell[j]),或者在当前持有股票的基础上卖出股票(buy[j] + prices[i])。

  • 时间复杂度O(k * n),其中 n 是天数,k 是交易次数。

  • 空间复杂度O(k),只需要两个长度为 k+1 的数组。

【C++】

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int days = prices.size();
        if(days < 2) {
            return 0;
        }
        if (k >= days) {
            int maxProfit = 0;
            for (int i = 1; i < days; ++i) {
                if (prices[i] > prices[i - 1]) {
                    maxProfit += prices[i] - prices[i - 1];
                }
            }
            return maxProfit;
        }
        vector<int> buy(k + 1, INT_MIN), sell(k + 1, 0);
        for (int i = 0; i < days; ++i) {
            for (int j = 1; j <= k; ++j) {
                buy[j] = max(buy[j], sell[j - 1] - prices[i]);
                sell[j] = max(sell[j], buy[j] + prices[i]);
            }
        }
        return sell[k];
    }
};

【Java】

class Solution {
    public int maxProfit(int k, int[] prices) {
        int days = prices.length;
        if (days < 2) {return 0;}
        if (k >= days) {
            int maxProfit = 0;
            for (int i = 1; i < days; ++i) {
                if (prices[i] > prices[i - 1]) {
                    maxProfit += prices[i] - prices[i - 1];
                }
            }
            return maxProfit;
        }
        int[] buy = new int[k + 1];
        Arrays.fill(buy, Integer.MIN_VALUE);
        int[] sell = new int[k + 1];
        for (int i = 0; i < days; ++i) {
            for (int j = 1; j <= k; ++j) {
                buy[j] = Math.max(buy[j], sell[j-1] - prices[i]);
                sell[j] = Math.max(sell[j], buy[j] + prices[i]);
            }
        }
        return sell[k];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贫道绝缘子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值