【LeetCode 面试经典150题】188. Best Time to Buy and Sell Stock IV 买卖股票的最佳时机 IV

188. Best Time to Buy and Sell Stock IV(买卖股票的最佳时机 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: i.e. you may buy at most k times and sell at most k times.

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

中文释义

给定一个整数数组 prices,其中 prices[i] 是第 i 天给定股票的价格,以及一个整数 k

找出你能获得的最大利润。你最多可以完成 k 笔交易:即你最多可以买入 k 次,卖出 k 次。

注意:你不能同时进行多笔交易(即,你必须在再次购买前出售股票)。

示例

  • 示例 1:
    • 输入:k = 2, prices = [2,4,1]
    • 输出:2
    • 解释:第 1 天买入(价格 = 2)并在第 2 天卖出(价格 = 4),利润 = 4-2 = 2。
  • 示例 2:
    • 输入:k = 2, prices = [3,2,6,5,0,3]
    • 输出:7
    • 解释:第 2 天买入(价格 = 2)并在第 3 天卖出(价格 = 6),利润 = 6-2 = 4。然后第 5 天买入(价格 = 0)并在第 6 天卖出(价格 = 3),利润 = 3-0 = 3。

限制条件

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

解题思路

使用动态规划(DP)来解决问题。当 k 过大时,问题转化为不限交易次数的情况。

步骤说明

  1. 初始化一个三维 dp 数组,dp[i][j][0] 表示第 i 天进行了 j 次交易后手里没有股票的最大利润,dp[i][j][1] 表示第 i 天进行了 j 次交易后手里有股票的最大利润。
  2. 遍历股票价格数组:
    • 如果 i 为 0,进行初始化。
    • 否则,更新 dp 数组的值。
  3. 返回 dp[n - 1][k][0] 作为结果。

代码

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();
        if (n == 0) return 0;

        if (k >= n / 2) {
            int profit = 0;
            for (int i = 1; i < n; i++) {
                profit += max(prices[i] - prices[i-1], 0);
            }
            return profit;
        }

        vector<vector<vector<int>>> dp(n, vector<vector<int>>(k + 1, vector<int>(2, 0)));

        for (int i = 0; i < n; i++) {
            for (int j = 1; j <= k; j++) {
                if (i == 0) {
                    dp[i][j][0] = 0;
                    dp[i][j][1] = -prices[i];
                } else {
                    dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
                    dp[i][j][1] = max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
                }
            }
        }

        return dp[n - 1][k][0];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值